Понимание выравнивания слов

Я понимаю, что значит обращаться к памяти так, чтобы она была выровнена, но не понимаю, зачем это нужно. Например, почему я могу получить доступ к одному байту с адреса 0x…1, но не могу получить доступ к полуслову (двум байтам) с того же адреса.

Опять же, я так понимаю, что если у вас адрес A и объект размером s то доступ выравнивается, если A mod s = 0. Но я просто не понимаю, почему это важно на аппаратном уровне.


person ChrisDiRulli    schedule 18.10.2009    source источник


Ответы (4)


Оборудование сложное; это упрощенное объяснение.

Типичный современный компьютер может иметь 32-битную шину данных. Это означает, что любая выборка, которую должен выполнить ЦП, будет извлекать все 32 бита определенного адреса памяти. Так как шина данных не может получить данные размером менее 32 бит, младшие два бита адреса даже не используются на адресной шине, поэтому создается впечатление, что ОЗУ организовано в виде последовательности 32-битных слов вместо 8-битных байтов.

Когда ЦП выполняет выборку одного байта, цикл чтения на шине извлекает 32 бита, а затем ЦП отбрасывает 24 из этих битов, загружая оставшиеся 8 бит в любой регистр. Если ЦП хочет получить 32-битное значение, которое не выровнено по 32-битной границе, у него есть несколько общих вариантов:

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

Различные процессоры, с которыми я работал, пошли по всем четырем этим путям. В общем, для максимальной совместимости безопаснее всего выровнять все n-битные операции чтения по n-битной границе. Тем не менее, вы, безусловно, можете использовать ярлыки, если уверены, что ваше программное обеспечение будет работать на каком-то конкретном семействе процессоров с известным невыровненным поведением чтения. И даже если чтение без выравнивания возможно (например, на процессорах семейства x86), оно будет медленнее.

person Greg Hewgill    schedule 18.10.2009
comment
младшие два бита адреса даже не используются на адресной шине Если да, то как 32-битный адрес адресуется всего 30-битным? Поправьте меня, если я ошибаюсь. - person jblixr; 01.03.2017
comment
да, эта часть требует уточнения. Два младших бита он упоминает дважды. Во втором решении кажется, что он может сделать одно чтение вместо двух, что также не имеет смысла, поскольку мы сказали, что оно не выровнено. - person David 天宇 Wong; 10.06.2021
comment
разве это не младшие 5 бит, которые должны быть установлены в 0 - person David 天宇 Wong; 10.06.2021

Компьютер всегда считывает некоторые фрагменты фиксированного размера, которые выровнены.

Итак, если вы не выравниваете свои данные в памяти, вам, вероятно, придется читать более одного раза.

Пример

  • размер слова 8 байт
  • ваша структура тоже 8 байт
  • если вы выровняете его, вам придется прочитать один кусок
  • если вы не выровняете его, вам придется прочитать два куска

Так что, в основном, для ускорения.

person Etan    schedule 18.10.2009

Причина всех правил выравнивания заключается в разной ширине строк кэша (кэш инструкций имеет 16-байтовые строки для архитектуры Core2, а кэш данных имеет 64-байтовые строки для L1 и 128 строк). -байтовые линии для L2).

Поэтому, если вы хотите хранить/загружать данные, которые пересекают границу Cahce-Line, вам нужно загружать и сохранять обе Cache-линии, что влияет на производительность. Так что вы просто не делаете этого из-за удара по производительности, это так просто.

person Quonux    schedule 14.07.2010
comment
не могли бы вы уточнить свой ответ подробнее? звучит интересно. современные процессоры редко обращаются к памяти напрямую. то, из чего они на самом деле извлекают данные, - это кеш. так что выравнивание слов должно иметь какое-то отношение только к кешу? огромное спасибо - person KawaiKx; 09.03.2011

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

Если у вас есть структура C, элементы которой не выровнены по словам (скажем, из-за обратной совместимости или экономии памяти), то адрес любого байта в структуре не выровнен по словам.

person Tim Williscroft    schedule 19.10.2009