sfence
(SSE1) и mfence
/ lfence
(SSE2) являются единственными инструкциями, которые названы для их функций ограничения / барьера памяти . Если вы не используете загрузку или хранение NT и / или память WC, для упорядочения памяти требуется только mfence
.
(Обратите внимание, что lfence
на процессорах Intel также является барьером для выполнения не по порядку, поэтому он может сериализовать rdtsc
и полезен для смягчения Спектра для предотвращения спекулятивного выполнения. Вкл AMD, есть MSR, который нужно установить, в противном случае lfence
- это, в основном, nop
(пропускная способность 4 / такта). Этот MSR был введен с обновлениями микрокода с подавлением помех и обычно устанавливается обновленными ядрами.)
lock
ed инструкции, такие как lock add [mem], eax
, также являются полными барьерами памяти . Имеет ли блокировка xchg то же поведение, что и mfence? . (Хотя, возможно, не так сильно, как mfence
для упорядочивания загрузок NT из памяти WC: Обеспечивают ли заблокированные инструкции барьер между слабо упорядоченными доступами? ). xchg [mem], reg
имеет неявный префикс lock
, поэтому он также является барьером.
В моих тестах на Skylake , lock
инструкции ed блокируют переупорядочение хранилищ NT с обычными хранилищами с этим кодом https://godbolt.org/g/7Q9xgz.
xchg
представляется хорошим способом создания хранилища seq-cst, особенно на оборудовании Intel, например Skylake, где mfence
также блокирует неупорядоченное выполнение простых инструкций ALU , например lfence
: см. конец этого ответа .
AMD также рекомендует использовать xchg
или другие заблокированные инструкции вместо mfence
. (mfence
задокументировано в руководствах AMD как сериализация на AMD, поэтому всегда будет штраф за блокировку OoO exec).
Для хранилищ с последовательной согласованностью или полных барьеров на 32-разрядных целевых объектах без SSE компиляторы обычно используют lock or [esp], 0
или другую команду блокировки без операции просто для барьера памяти эффект. Вот что g++7.3 -O3 -m32 -mno-sse
делает для std::atomic_thread_fence(std::memory_order_seq_cst);
.
Но в любом случае ни mfence
, ни lock
ed insns архитектурно не определены как сериализация на Intel, независимо от деталей реализации на некоторых процессорах.
Инструкции полной сериализации, такие как cpuid
, также являются полными барьерами памяти , которые освобождают буфер хранения и очищают конвейер. Имеет ли блокировка xchg такое же поведение, как и у mfence? имеет соответствующие цитаты из руководства Intel.
На процессорах Intel нижеприведены архитектурно-последовательные инструкции (От: https://xem.github.io/minix86/manual/intel-x86-and-64-manual-vol3/o_fe12b1e2a880e0ce-273.html):
Привилегированные инструкции сериализации - INVD, INVEPT, INVLPG, INVVPID, LGDT, LIDT, LLDT, LTR, MOV для управления регистром, MOV (для отладки регистра), WBINVD и WRMSR.
Исключения: MOV CR8
не сериализуется. WRMSR
для MSR IA32_TSC_DEADLINE (индекс MSR 6E0H) и MSR X2APIC (индексы MSR от 802H до 83FH) не сериализуются.
Непривилегированные инструкции сериализации - CPUID, IRET 1 и RSM
На процессорах AMD следующие архитектурно-последовательные инструкции:
Привилегированные инструкции сериализации - INVD, INVLPG, LGDT, LIDT, LLDT, LTR, MOV для управления регистром, MOV (для отладки регистра), WBINVD, WRMSR и SWAPGS.
Непривлекательные команды сериализации - MFENCE, CPUID, IRET и RSM
Термин «[полностью] инструкция сериализации» на процессорах Intel означает то же самое, что и на процессорах AMD, за исключением одного различия: операция очистки строки кэша от CLFLUSH
(но не CLFLUSHOPT
) упорядочена относительно более поздние инструкции только на MFENCE
на процессорах AMD.
in
/ out
(и их версии для копирования строк ins
и outs
) являются полными барьерами памяти, а также частично сериализуются (как lfence
). В документах говорится, что они задерживают выполнение следующей инструкции до «фазы данных» транзакции ввода / вывода.
Сноска:
(1) Согласно BJ137 (Песчаный мост), HSD152 (Haswell), BDM103 (Broadwell):
Проблема: инструкция IRET, приводящая к переключению задачи
возврат из вложенного задания не сериализует процессор
(вопреки разделу Руководства разработчика ПО, том 3, озаглавленному
«Инструкция по сериализации»).
Вывод: программное обеспечение, зависящее от сериализации
свойство IRET при переключении задач может не работать как
ожидается. Intel не наблюдала эту ошибку, чтобы повлиять на
работа любого имеющегося в продаже программного обеспечения.
Обходной путь: Не идентифицирован. Программное обеспечение может выполнить MFENCE
инструкция непосредственно перед инструкцией IRET, если сериализация
нужен.