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

StackOverflow https://stackoverflow.com/questions/1054657

Вопрос

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

Во-первых, верен ли этот вывод?

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

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

Это было полезно?

Решение

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

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

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

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

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

Другие советы

Ширина физической шины составляет 64 бита ...кратно 8 -> да

ОДНАКО есть еще два фактора, которые следует учитывать:

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top