Выравнивание памяти на 32-разрядном процессоре Intel

if(Number.isInteger(Number(data))){
    //-----
}
14
задан Frederick The Fool 28 June 2009 в 10:18
поделиться

5 ответов

Обычное практическое правило (прямо из руководств Intel и AMD по оптимизации) состоит в том, что каждый тип данных должен быть выровнен по своему размеру. int32 должен быть выровнен по 32-битной границе, int64 по 64-битной границе и так далее. Знаки char подойдут где угодно.

Другое практическое правило - конечно, «компилятору сообщили о требованиях к выравниванию». Вам не нужно беспокоиться об этом, потому что компилятор знает, как добавить правильные отступы и смещения, чтобы обеспечить эффективный доступ к данным.

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

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

Я не понимаю, как это имеет значение. ЦП может просто выполнить чтение 64-битного блока, содержащего эти 4 байта. Это означает, что он получает либо 4 дополнительных байта перед запрошенными данными, либо после них. Но в обоих случаях требуется только одно чтение. 32-битное выравнивание 32-битных данных гарантирует, что они не пересекают 64-битную границу.

14
ответ дан 1 December 2019 в 12:01
поделиться

Физическая шина имеет ширину 64 бита ... кратно 8 -> да

ОДНАКО, необходимо учитывать еще два фактора:

  1. Некоторые наборы инструкций x86 байт адресован. Некоторые из них выровнены по 32 бита (поэтому у вас есть 4 байта). Но никакая (основная) инструкция не выравнивается на 64 бита. ЦП может обрабатывать несогласованный доступ к данным.
  2. Если вам важна производительность, вы должны думать о строке кэша, а не об основной памяти. Строки кэша намного шире.
7
ответ дан 1 December 2019 в 12:01
поделиться

Для произвольного доступа и до тех пор, пока данные не смещены (например, пересекают границу), я не думаю, что это имеет большое значение; правильный адрес и смещение в данных можно найти с помощью простой аппаратной конструкции AND. Он становится медленным, когда одного доступа на чтение недостаточно для получения одного значения. Вот почему компиляторы обычно объединяют небольшие значения (байты и т. Д.), Потому что они не обязательно должны иметь определенное смещение; шорты должны быть на четных адресах, 32-битные на 4-байтовых адресах и 64-битные на 8-байтовых адресах.

Обратите внимание, что если у вас есть кэшируемый активный и линейный доступ к данным, все будет иначе.

1
ответ дан 1 December 2019 в 12:01
поделиться

Это оправдано, потому что изменение на 8-байтовое выравнивание означало бы изменение ABI, а незначительное улучшение производительности не стоит проблем.

Как уже было сказано, кешлины имеют значение. Все обращения к фактической шине памяти осуществляются в виде строк кэша (64 байта на x86, IIRC). См. Уже упомянутый документ «Что нужно знать каждому программисту о памяти». Таким образом, фактический трафик памяти выравнивается по 64 байтам.

2
ответ дан 1 December 2019 в 12:01
поделиться

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

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

1
ответ дан 1 December 2019 в 12:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: