CPU и выравнивание данных

извините меня, если вы считаете, что на это ответили много раз, но мне нужны ответы на следующие вопросы!

  1. Почему данные должны быть выровнены (по 4 байта/ 8 байт/ 2 байта)? Здесь я сомневаюсь, когда процессор имеет адресные строки Ax Ax-1 Ax-2 ... A2 A1 A0 тогда вполне возможно последовательно обращаться к местам памяти. Итак, почему существует необходимость выравнивания данных на определенных границах?

  2. Как найти выравнивание требования, когда я компилирую свой код и генерирую executatble?

  3. Если для e.G выравнивание данных-граница 4 байта, означает ли это, что каждый последовательный байт находится на смещениях по модулю 4? Мои сомнения, если данных 4 байт означает ли это, что если байт на 1004 затем следующий байт по 1008 (или 1005)?

7 ответов


процессоры ориентированы на слово,а не на байт. В простом процессоре память обычно настроена на возврат одного слово (32bits, 64bits и т. д.) На строб адреса, где нижние две (или более) адресные строки, как правило, не заботятся о битах.

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

некоторые процессоры (ARM или инструкции Intel SSE) требуют выровненной памяти и имеют неопределенную операцию при выполнении не выровненных обращений (или создают исключение). Они экономят значительное пространство кремния, не реализуя гораздо более сложную подсистему загрузки/хранения.

выравнивание зависит от размера слова CPU (16, 32, 64bit) или в случае SSE размер регистра SSE (128 бит).

для вашего последнего вопроса, если вы загружаете один байт данных за раз на большинстве процессоров нет ограничений выравнивания (некоторые DSP не имеют инструкций уровня байтов, но, скорее всего, вы не столкнетесь с ними).


очень мало данных "должно" быть выровнено. Более того, некоторые типы данных могут работать лучше или определенные операции ЦП требуют определенного выравнивания данных.

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

теперь, поскольку вы можете загрузить 4 байта данных сразу, не имеет смысла регистрировать Ваш адрес укажите на один байт. Сделав адресную точку регистра каждые 4 байта, вы можете манипулировать данными в 4 раза больше. Другими словами, ваш процессор может только читать данные, начиная с байтов 0, 4, 8, 12, 16, etc.

Итак, вот в чем проблема. Если вы хотите, чтобы данные начинались с байта 2, и Вы читаете 4 байта, то половина ваших данных будет в адресной позиции 0, а другая половина-в позиции 1.

Так что в основном вы бы в конечном итоге попали в память дважды, чтобы прочитать один 4 байт элемент данных. Некоторые процессоры не поддерживают такого рода операции (или заставляют вас загружать и комбинировать два результата вручную).

дополнительные сведения см. здесь: http://en.wikipedia.org/wiki/Data_structure_alignment


1.) Некоторые архитектуры вообще не имеют этого требования, некоторые поощряют выравнивание (существует штраф скорости при доступе к элементам данных не-alignet), а некоторые могут строго применять его (рассогласование вызывает исключение процессора).
Многие из сегодняшних популярных архитектур попадают в категорию штрафов за скорость. Проектировщики ЦП должны были торговать между гибкостью / производительностью и стоимостью (площадь кремния/количество управляющих сигналов, необходимых для циклов шины).

2.) Что язык, какая архитектура? Обратитесь к руководству по компиляторам и / или документации по архитектуре ЦП.

3.) Опять же, это полностью зависит от архитектуры (некоторые архитектуры могут вообще не разрешать доступ к элементам размером в байт или иметь ширину шины, которая даже не кратна 8 битам). Так что, если вы не спрашиваете о конкретные архитектура вы не получите никаких полезных ответов.


В общем, один ответ на все три из этих вопросов - "это зависит от вашей системы". Подробнее:

  1. ваша система памяти может быть не байт-адресуемой. Кроме того, вы можете понести штраф за производительность, чтобы ваш процессор имел доступ к несогласованным данным. Некоторые процессоры (например, старые чипы ARM) просто не могут этого сделать.

  2. прочитайте руководство для вашего процессора и любой спецификации ABI ваш код генерируется для,

  3. обычно, когда люди ссылаются на данные, находящиеся на определенном выравнивании, это относится только к первому байту. Поэтому, если спецификация ABI сказала: "структура данных X должна быть выровнена по 4 байтам", это означает, что X должен быть помещен в память по адресу, который делится на 4. Ничто не подразумевается этим утверждением о размере или внутреннем расположении структуры X.

    Что касается вашего конкретного примера, если данные выровнены по 4 байтам, начиная с адреса 1004, следующий байт будет на 1005.


его полностью зависит от процессора, который вы используете!

некоторые архитектуры имеют дело только с 32 (или 36!) битные слова, и вам нужны специальные инструкции для загрузки символов singel или слов haalf.

некоторые процессоры (особенно PowerPC и другие чипы IBM risc) не заботятся о выравниваниях и загружают целые числа из нечетных адресов.

для большинства современных архитектур вам нужно выровнять целые числа в слова и длинные целые числа, чтобы удвоить границы слов. Это упрощает цирк для загрузки регистров и ускоряет все так слабо.


выравнивание данных требуется CPU по причине производительности. Сайт Intel выдаст подробную информацию о том, как выровнять данные в памяти

выравнивание данных при переходе на 64-разрядную архитектуру Intel®

одним из них является выравнивание элементов данных – их расположение в памяти по отношению к адресам, кратным четырем, восьми или 16 байтам. Под 16-битной архитектурой Intel выравнивание данных было мало влияние на производительность, и ее использование совершенно не обязательно. В IA-32 правильное выравнивание данных может быть важной оптимизацией, хотя его использование по-прежнему является необязательным, за очень редкими исключениями, где правильное выравнивание является обязательным. Однако 64-разрядная среда предъявляет более жесткие требования к элементам данных. Несоосные объекты вызывают исключения программы. Чтобы элемент был правильно выровнен, он должен соответствовать требованиям, предъявляемым 64-разрядной архитектурой Intel (обсуждается в ближайшее время), а также компоновщика, используемого для создания приложения.

основное правило выравнивания данных заключается в том, что самый безопасный (и наиболее широко поддерживаемый) подход основан на том, что Intel называет "естественными границами"."Это те, которые происходят, когда вы округляете размер элемента данных до следующего по величине размера два, четыре, восемь или 16 байт. Например, 10-байтовый float должен быть выровнен по 16-байтовому адресу, тогда как 64-разрядные целые числа должны быть выровнены по 8-байтовому адресу. Потому что это 64-разрядная архитектура, размеры указателей все восемь байт в ширину, и поэтому они тоже должны выравниваться по восьмибайтовым границам.

рекомендуется, чтобы все структуры размером более 16 байт выравнивались по 16-байтовым границам. В общем, для лучшей производительности выровняйте данные следующим образом:

  • выровнять 8-битные данные по любому адресу
  • выровнять 16-битные данные, которые будут содержаться в выровненном четырехбайтовом слове
  • выровнять 32-разрядные данные, так что его базовый адрес кратен четырем
  • выровнять 64-разрядные данные так, чтобы его базовый адрес был кратен восьми
  • выровнять 80-битные данные так, чтобы его базовый адрес кратен шестнадцати
  • выровнять 128-битные данные так, чтобы его базовый адрес кратен шестнадцати

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

правильное выравнивание данных в структурах может привести к раздуванию данных (из - за заполнения, необходимого для правильного размещения полей), поэтому, когда это необходимо и возможно, полезно реорганизовать структуры так поля, требующие самого широкого выравнивания, являются первыми в структуре. Подробнее о решении этой проблемы см. В статье " Подготовка кода для архитектуры IA-64 (Code Clean)."


для архитектуры Intel, Глава 4 типы данных Intel 64 и IA-32 архитектуры руководство разработчика программного обеспечения ответ на ваш вопрос 1.