совместимость модели программатора amd и intel

Я прочитал Руководство по разработке программного обеспечения Intel (том 1-3).

Не выполняя аналогичное чтение руководств по программированию AMD (том 1-5), мне интересно, какие аспекты модели программирования Intel и AMD одинаковы.

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

Тем не менее, Intel делает некоторые общие заявления о простых вещах, которые, в целом, я не уверен, относятся ли они к AMD. Например:

  • Размер строки кэша
  • Гарантированный порядок памяти для каждого типа памяти
  • Atomic r/w гарантии для каждого типа памяти
  • ЭСТ.

Заметьте, я не спрашиваю конкретно об этих примерах. Я спрашиваю, с точки зрения программиста, с точки зрения написания функционально эквивалентного кода, эквивалентны ли модели программирования AMD и Intel?

(Здесь речь идет только об архитектурах AMD64 и Intel 64)


person Abel    schedule 26.01.2019    source источник
comment
Эй, Питер. Спасибо за подробный ответ - не только ответ на вопрос, но и предоставление очень актуальных примеров.   -  person Abel    schedule 26.01.2019


Ответы (1)


В общем, не совсем, модель программирования не всегда полностью эквивалентна. Вам нужно проверить оба набора документов, если вы хотите быть на 100% уверены.

https://en.wikipedia.org/wiki/X86-64#Differences_between_AMD64_and_Intel_64

например bsf/bsr: в документах Intel говорится, что они оставляют место назначения неопределенным, AMD говорит, что оставляет его без изменений на нуле. Но на практике Intel делает это с микроархитектурной зависимостью от выходного регистра. Эта ложная зависимость также заразила lzcnt/tzcnt до Skylake, и еще popcnt, на Intel, но не на AMD. Но пока Intel не изложит на бумаге, что они будут продолжать заставлять свое аппаратное обеспечение вести себя таким образом, компиляторы не смогут воспользоваться этим, и мы, возможно, не должны делать это вручную.

(Похоже, Википедия говорит, что в Intel старшие 32 бита адресата могут быть неопределенными, а не обнуленными, для bsr/bsf eax, ecx в Intel. Так что это не совсем то же самое, что всегда писать EAX. Я могу подтвердить это на SKL i7- 6700k: mov rax,-1 ; bsf eax, ecx (с нулевым ECX) оставляет RAX=-1 (64-битный), а не усекается до 2 ^ 32-1.Но с ненулевым ECX запись EAX имеет обычный эффект расширения нуля в RAX. )


Это особенно важно для кода ядра, поведение привилегированных инструкций может иметь более тонкие различия. Я думаю, что семантика аннулирования TLB в основном совпадает, например. на обоих гарантируется, что вам не нужно аннулировать TLB после изменения недопустимой записи на действительную. Таким образом, x86 запрещает «негативное кэширование», поэтому реализация, которая хотела бы это сделать, должна была отслеживать хранилища таблиц страниц для согласованности.

Некоторые из них, вероятно, непреднамеренны, например, у Intel и AMD есть разные ошибки для sysret с неканоническими адресами x86-64, что делает его небезопасным для использования после того, как системный вызов ptrace мог изменить сохраненный RIP. Потенциальная ошибка GP может произойти в режиме ядра после переключения на пользовательский стек, передавая управление ядром другому потоку пользовательского пространства из того же процесса, который может изменять эту память стека. (https://blog.xenproject.org/2012/06/13/the-intel-sysret-privacy-escalation/) Вот почему Linux всегда использует iret, за исключением обычного быстрого пути, когда сохраненные регистры заведомо чисты. Комментарии в entry_64.S исходного кода ядра бит


Гарантии атомарности для невыровненных кэшированных загрузок/сохранений слабее на AMD: из-за AMD границы размером всего 8 байт могут иметь значение на x86-64. Почему целочисленное назначение на естественно выровненная переменная atomic на x86? охватывает общее подмножество этого.


Размер строки кэша никогда официально не стандартизировался. На практике процессоры Intel и AMD используют 64-байтовые строки, и их можно запрашивать во время выполнения, используя CPUID одинаково на обоих.


Насколько я знаю, правила порядка памяти идентичны, по крайней мере, для WB и, вероятно, для других типов, включая WC и взаимодействие с LFENCE/SFENCE/MFENCE против lock add. Хотя в Intel четко не задокументировано, должны ли lock и xchg отличаться от mfence. Но вы спрашиваете о самой модели программирования, а не только о том, что написано в документах. См. Поведение блокировки xchg такое же, как у mfence? и Что такое разница в логике и производительности между LOCK XCHG и MOV+MFENCE?

IDK об AMD, но загрузки NT WC могут переупорядочиваться с lock add / xchg на Intel (но они не должны с MFENCE, я думаю, и поэтому обновление ucode Intel должно было усилить MFENCE на Skylake, чтобы заблокировать OoO exec, как другие LFENCE эффект, чтобы последующие загрузки вообще не попадали в канал.) Ответ @Bee по первой ссылке упоминает об этом и см. нижнюю часть этого. При тестировании реального оборудования всегда трудно сказать, какое поведение гарантировано в будущем, а что является просто деталями реализации, и здесь на помощь приходят руководства.

person Peter Cordes    schedule 26.01.2019
comment
В Википедии есть неполный список. Кроме того, функциональные возможности, правила упорядочения и/или исключения, которые могут быть вызваны следующими инструкциями, различаются на процессорах Intel и AMD: инструкции ограждения, инструкции предварительной выборки, инструкции сериализации и clflush. Правила само- и кросс-модифицирующего кода различаются. Существуют различия в правилах упорядочения памяти для типов памяти, отличных от WB. Существуют также различия в том, как определенные инструкции или события влияют на TLB. - person Hadi Brais; 26.01.2019
comment
Вероятно, есть много других очень тонких различий между x86 на Intel и AMD. Отсутствие формализма затрудняет определение их всех. - person Hadi Brais; 26.01.2019
comment
Исправлена ​​popcnt ложная зависимость на Cannon Lake. - person BeeOnRope; 30.01.2019