Выравнивание памяти на 32-битном процессоре Intel - PullRequest
13 голосов
/ 28 июня 2009

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

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

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

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

Ответы [ 5 ]

14 голосов
/ 28 июня 2009

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

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

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

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

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

6 голосов
/ 28 июня 2009

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

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

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

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

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

1 голос
/ 06 августа 2009

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

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

1 голос
/ 28 июня 2009

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

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

...