Задать вопрос

Зачем нужно выравнивание памяти по слову?

Почему это добавляет эффективности программному коду? Что мешает адресоваться по нечетным адресам и почему структура

struct block{
char a;
char b;
char* c;
};


занимает не 16, а 8 байт (в 32 битной программе)? Если компилятор генерирует вместо этой структуры такую
struct decoratedblock{
char a;
char zero[1];
char b;
char zero[1];
char* c;
};


Получается, что b может находится по адресу, не кратному машинному слову в 32 бита. Почему между a и b не 3, а 1 нулевой байт? Подскажите пожалуйста, немного запутался
  • Вопрос задан
  • 2909 просмотров
Подписаться 3 Простой 3 комментария
Решения вопроса 4
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Большинство современных процессоров читают данные из памяти не отдельными байтами, а блоками по 2-4-8 байт. Соответственно, если у вас данные не выравнены в памяти и начало попадает в один блок, а конец в другой, то для чтения надо будет получить два таких блока.
Ответ написан
@MarkusD Куратор тега C++
все время мелю чепуху :)
Разобраться с вопросом тебе поможет статья: Расставим точки над структурами C/C++.
Если точнее, то тебе стоит детально изучить первый же пункт статьи: Выравнивание полей памяти.
В общем выравниваются в памяти поля по границе кратной своему же размеру. То есть 1-байтовые поля не выравниваются, 2-байтовые — выравниваются на чётные позиции, 4-байтовые — на позиции кратные четырём и т.д.
Ответ написан
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Я не знаю, можно ли такого уровня детали найти для современных процессоров, а вот для i80386 в спецификации, в разделе 5.3.6 легко можно видеть, что невыравненный доступ к памяти занимает два цикла, вместо одного.
За пределами мира x86 многие процессоры вообще не поддерживают доступ к невыравненным данным на аппаратном уровне.
Ответ написан
Комментировать
WNeZRoS
@WNeZRoS
В подтверждение слов Rsa97 и zedxxx могу привести код на godbolt.
Там выбрана архитектура ARM, так как там хорошо видно разницу из-за его простоты.

В жёлтом блоке ассемблерного кода происходит побайтовое чтение поинтера из байт 3, 4, 5, 6 и его склеивание, т.к. отключено выравнивание.
В голубом блоке происходит чтение сразу всего поинтера потому что он выровнен.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Punk_Joker
@Punk_Joker
Software Engineer в ВО Овен
Потому что размер указателя 4 байта, вот и остальные элементы выровнены на 4
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы