Что означает выравнивание по 16-байтовой границе в x86

официальное руководство по оптимизации Intel имеет главу о преобразовании из команд MMX в SSE, где они указывают состояние под паром:

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

(глава 5.8 преобразование из 64-битного в 128-битный SIMD Целые числа, pg. 5-43)

Я не могу понять, что они подразумевают под "не может быть выровнено по 16-байтовой границе", не могли бы Вы уточнить его и привести несколько примеров?

3 ответов


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

Так что в вашем случае выравнивание на 16 байт (128 бит), что означает, что адрес памяти данных должен быть кратен 16. Е. Г. 0x00010 будет выровнено 16 байт, в то время как 0x00011 не будет.

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


данные, выровненные по 16-битной границе, будут иметь адрес памяти, который является четным числом, строго говоря, кратным двум. Каждый байт составляет 8 бит, поэтому для выравнивания по 16-битной границе вам нужно выровнять каждый набор из двух байтов.

аналогично, память, выровненная по 32-битной границе, будет иметь адрес памяти, кратный четырем, потому что вы группируете четыре байта вместе, чтобы сформировать 32-битное слово.


Я предполагаю здесь, но может ли быть, что "не может быть выровнен по 16-байтовой границе" означает, что это место памяти было выровнено по меньшему значению (4 или 8 байтов) раньше для некоторых других целей и теперь для выполнения инструкций SSE на этой памяти вам нужно явно загрузить его в регистр?