Подтвердить что ты не робот

Выравнивание памяти на 32-разрядном процессоре Intel

32-разрядные процессоры Intel, такие как Pentium, имеют 64-битную шину данных и, следовательно, извлекают 8 байтов на каждый доступ. Исходя из этого, я предполагаю, что физические адреса, которые эти процессоры испускают на адресной шине, всегда имеют кратность 8.

Во-первых, верно ли это заключение?

Во-вторых, если это правильно, то следует выровнять элементы структуры данных на 8-байтовой границе. Но я видел людей, использующих 4-байтовое выравнивание вместо этих процессоров.

Как они могут быть оправданы при этом?

4b9b3361

Ответ 1

Обычное эмпирическое правило (прямо из руководств по оптимизации Intels и AMD) заключается в том, что каждый тип данных должен быть выровнен по собственному размеру. int32 должен быть выровнен на 32-битной границе, int64 на 64-битной границе и т.д. A char подойдет только в любом месте.

Другое эмпирическое правило - конечно, "компилятор рассказал о требованиях к выравниванию". Вам не нужно беспокоиться об этом, потому что компилятор знает, что нужно добавить правильные дополнения и смещения, чтобы обеспечить эффективный доступ к данным.

Единственное исключение - при работе с инструкциями SIMD, где вам нужно вручную обеспечить выравнивание для большинства компиляторов.

Во-вторых, если это правильно, то один должен выровнять элементы структуры данных на 8-байтовая граница. Но я видел люди, использующие 4-байтовое выравнивание вместо этого на этих процессорах.

Я не понимаю, как это имеет значение. CPU может просто выдать чтение для 64-битного блока, который содержит эти 4 байта. Это означает, что он либо получает 4 дополнительных байта перед запрошенными данными, либо после него. Но в обоих случаях требуется только одно чтение. 32-битное выравнивание 32-битных данных гарантирует, что он не пересечет 64-битную границу.

Ответ 2

Физическая шина имеет ширину 64 бит... несколько из 8 → да

ОДНАКО, есть еще два фактора:

  • Некоторый набор инструкций x86 адресован байтом. Некоторые из них выровнены по 32 бита (поэтому у вас есть 4 байта). Но никакая (основная) команда не выровнена на 64 бита. ЦП может обрабатывать неверный доступ к данным.
  • Если вы заботитесь о производительности, вы должны думать о линии кэша, а не о основной памяти. Кэш-линии намного шире.

Ответ 3

Они оправданы тем, что переход к 8-байтовому выравниванию будет представлять собой изменение ABI, а предельное улучшение производительности не стоит проблем.

Как уже сказал кто-то еще, вопрос имеет значение. Все обращения к фактической шине памяти относятся к линиям кэша (64 байта на x86, IIRC). См. "Что каждый программист должен знать о памяти", который уже упоминался. Таким образом, фактический объем трафика памяти равен 64 байтам.

Ответ 4

Шина с 64 битами, на которую вы ссылаетесь, подает кеши. Как процессор, всегда читайте и записывайте целые строки кэша. Размер строки кэша всегда кратен 8, а его физический адрес действительно выровнен с 8-байтовыми смещениями.

Передача кэша в регистр не использует внешнюю шину данных, поэтому ширина этой шины не имеет значения.

Ответ 5

Для случайного доступа и пока данные не смещены (например, пересекают границу), я не думаю, что это имеет большое значение; правильный адрес и смещение в данных можно найти с помощью простой конструкции AND в аппаратном обеспечении. Он становится медленным, когда один доступ для чтения недостаточен для получения одного значения. Это также объясняет, почему компиляторы обычно помещают небольшие значения (байты и т.д.) Вместе, потому что они не должны быть с определенным смещением; шорты должны быть на четных адресах, 32-битных по 4-байтным адресам и 64-битных по 8-байтным адресам.

Обратите внимание, что если у вас есть кеширование и доступ к линейным данным, все будет по-другому.