Виртуальная память и выравнивание — как они связаны друг с другом?

Кажется, я понимаю выравнивание памяти, но меня смущает то, что адрес указателя в некоторых системах будет находиться в виртуальной памяти, верно? Таким образом, большая часть проверки/обеспечения выравнивания, которую я видел, просто использует адрес указателя. Не может быть, чтобы адрес физической памяти не был выровнен? Разве это не проблема для таких вещей, как SSE?


person Doug Moscrop    schedule 19.11.2011    source источник
comment
Я не эксперт по низкоуровневой модели памяти (включая выравнивание). Но я бы подумал, что страницы будут выровнены, и я предполагаю, что любой относительный указатель на этих страницах будет автоматически выровнен.   -  person Merlyn Morgan-Graham    schedule 19.11.2011
comment
Да, похоже, что я не понял, была виртуальная память.   -  person Doug Moscrop    schedule 19.11.2011


Ответы (2)


Физический адрес будет выровнен, потому что виртуальная память отображает только выровненные страницы в физическую память (и страницы обычно имеют размер 4 КБ).

Поэтому, если вам не нужно выравнивание > размер страницы, физическая память будет выровнена в соответствии с вашими требованиями.

В конкретном случае SSE все работает нормально, потому что вам нужно только выравнивание по 16 байтам.

person Anthony Blake    schedule 19.11.2011

Я не знаю ни одной реальной системы, в которой выровненный адрес виртуальной памяти может привести к смещению адреса физической памяти.

Как правило, все выравнивания на данной платформе будут степенью двойки. Например, в x86 32-битные целые числа имеют естественное выравнивание по 4 байтам (2^2). Размер страницы, определяющий, насколько мелкий блок можно отобразить в физической памяти, обычно представляет собой большую степень двойки. В x86 наименьший допустимый размер страницы составляет 4096 байт (2^12). Самый большой тип данных, который может потребовать выравнивания на x86, составляет 128 бит (для регистров XMM и CMPXCHG16B) 32 байта (для AVX) — 2^5. Поскольку 2 ^ 12 делится на 2 ^ 5, вы обнаружите, что все выравнивается в самом начале страницы, а поскольку страницы выравниваются как в виртуальной, так и в физической памяти, адрес с виртуальным выравниванием всегда будет выравниваться по физическому.

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

Обратите внимание, что у вас могут быть причины время от времени запрашивать выравнивание большего размера, чем страница. Как правило, для кодирования пользовательского пространства не имеет значения, выровнено ли оно в физическом ОЗУ (в этом отношении, если вы запрашиваете несколько страниц, они вряд ли будут даже смежными!). Проблемы здесь возникают только в том случае, если вы пишете драйвер устройства и вам нужен большой, выровненный, непрерывный блок для прямого доступа к памяти. Но даже в этом случае обычно устройство не является приверженцем выравнивания, превышающего размер страницы.

person bdonlan    schedule 19.11.2011
comment
Фактически, самый большой тип данных, который может потребовать выравнивания на x86, в настоящее время составляет 32 байта - для AVX. Есть также другие случаи, когда вы можете запросить выравнивание › 32 байта — нередко требуется, чтобы динамические выделения были выровнены по страницам. - person Anthony Blake; 19.11.2011