Выравнивание ЦП и данных

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

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

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

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

Ответ 1

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

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

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

Выравнивание зависит от размера слова процессора (16, 32, 64 бит) или SSE в регистре SSE (128 бит).

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

Ответ 2

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

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

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

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

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

Перейдите сюда для получения более подробной информации: http://en.wikipedia.org/wiki/Data_structure_alignment

Ответ 3

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

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

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

Ответ 4

В общем, один ответ на все три вопроса: "это зависит от вашей системы". Еще несколько деталей:

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

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

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

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

Ответ 5

Его полностью зависит от используемого вами процессора!

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

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

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

Ответ 6

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

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

  

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

         

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

         

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

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

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

         

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

  

Ответ 8

"Теперь, поскольку вы можете загружать сразу 4 байта данных, не имеет особого смысла, чтобы ваш регистр адресов указывал на один байт."

Почему? Почему я не могу читать позиции 1, 2, 3, 4 за раз? Я думаю, что это не ухудшит производительность и не усложнит схему?