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

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

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

Ответы

Ответ 1

Аппаратное обеспечение сложное; это упрощенное объяснение.

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

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

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

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

Ответ 2

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

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

Пример

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

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

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

У меня есть основной вопрос (может быть, немой): Почему эта память не была выровнена на первом месте? Я имею в виду, если вы читаете и записываете данные для данной машины, вы будете следовать ее правилам выравнивания. В 32-битной системе я обязательно буду записывать данные с 32-битным выравниванием.

Это что-то связано с упорядочением сетевых байтов?