Инструкции по ограждению x86 можно кратко описать следующим образом:
MFENCE предотвращает глобальное наблюдение за любой последующей загрузкой или сохранением перед любой более ранней загрузкой или сохранением. Он истощает буфер хранилища перед тем, как более поздние загрузки 1 могут выполнить.
LFENCE блокирует отправку инструкций (по терминологии Intel) до тех пор, пока не будут удалены все предыдущие инструкции. В настоящее время это реализуется путем осушения ROB (буфера повторного заказа) до того, как последующие инструкции смогут передать в серверную часть.
SFENCE упорядочивает хранилища только по отношению к другим хранилищам, то есть предотвращает фиксацию хранилищ NT из буфера хранилища перед самой SFENCE. Но в остальном SFENCE похожа на обычное хранилище, которое перемещается через буфер хранилища. Думайте об этом, как о том, как поставить разделитель на конвейерную ленту кассового магазина в продуктовом магазине, который не дает магазинам NT забираться раньше времени. Это не обязательно принудительно очищает буфер хранилища до того, как он удалится из ROB, поэтому установка LFENCE после этого не дает в сумме MFENCE.
Команда сериализации, такая как CPUID (и IRET и т. Д.), Истощает все (ROB, буфер хранилища) до того, как последующие инструкции могут быть переданы в серверную часть. MFENCE + LFENCE также сделает это, но настоящие инструкции сериализации могут иметь и другие эффекты, я не знаю.
Эти описания немного неоднозначны с точки зрения того, какие именно операции заказываются, и есть некоторые различия между поставщиками (например, SFENCE сильнее на AMD) и даже процессорами от одного поставщика. Обратитесь к руководству Intel и обновлениям спецификаций, а также к руководству AMD и руководствам по версиям для получения дополнительной информации. Есть также много других обсуждений этих инструкций в других местах. Но сначала прочтите официальные источники. Приведенные выше описания, я думаю, являются минимальным указанным на бумаге поведением поставщиков.
Сноска 1: OoO exec более поздних хранилищ не нужно блокировать с помощью MFENCE; их выполнение просто записывает данные в буфер хранилища. Фиксация по порядку уже заказывает их после предыдущих магазинов и фиксирует после списания заказов. загружает (потому что x86 требует, чтобы загрузка была завершена, а не только началась, прежде чем они могут быть отключены, как часть обеспечения порядка загрузки). Помните, что оборудование x86 построено так, чтобы запрещать переупорядочивание, отличное от StoreLoad.
В руководстве Intel, том 2, номер 325383-072US, SFENCE описывается как инструкция, которая гарантирует, что каждое хранилище до SFENCE будет глобально видимым до того, как любое хранилище после SFENCE станет глобально видимым. Раздел 11.10 тома 3 говорит, что буфер хранилища опустошается при использовании SFENCE. Правильная интерпретация этого утверждения - это в точности предыдущее утверждение из тома 2. Таким образом, можно сказать, что SFENCE истощает буфер хранилища в этом смысле. Нет гарантии, в какой момент в течение жизненного цикла SFENCE более ранние магазины достигнут GO. Для любого более раннего магазина это могло произойти до, во время или после прекращения работы SFENCE. Что касается смысла GO, это зависит от нескольких факторов. Это выходит за рамки вопроса. См .: Почему «movnti», за которым следует «sfence», гарантирует постоянное заказ?.
MFENCE действительно должен предотвращать переупорядочивание хранилищ NT с другими хранилищами, поэтому он должен включать все, что делает SFENCE, а также очищать буфер хранилища. А также переупорядочение слабо упорядоченных загрузок SSE4.1 NT из памяти WC, что сложнее, потому что обычные правила, которые получают бесплатный порядок загрузки, к ним больше не применяются. Гарантия этого - вот почему обновление микрокода Skylake усилило (и замедлило) MFENCE., чтобы слить ROB как LFENCE. MFENCE все еще может иметь меньший вес, чем аппарат с поддержкой HW для необязательно принудительного упорядочивания NT-нагрузок в конвейере.
Основная причина, по которой SFENCE + LFENCE не равно MFENCE, заключается в том, что SFENCE + LFENCE не блокирует переупорядочение StoreLoad, поэтому этого недостаточно для последовательной согласованности. Только mfence
(или операция lock
ed, или настоящая инструкция сериализации, такая как cpuid
) сделает это. См. переупорядочение памяти, обнаруженное в действии Джеффа Прешинга, чтобы узнать случай, когда достаточно только полного барьера.
Из справочного руководства Intel для sfence
:
Процессор гарантирует, что каждое хранилище до SFENCE будет глобально видимым до того, как любое хранилище после SFENCE станет глобально видимым.
но
Он не упорядочен по загрузке памяти или инструкции LFENCE.
LFENCE заставляет более ранние инструкции выполняться локально (т. Е. Удаляться из вышедшей из строя части ядра), но для хранилища или SFENCE это просто означает размещение данных или маркера в буфере порядка памяти, а не его очистку, поэтому хранилище становится видимым во всем мире. т.е. завершение SFENCE (вывод из ROB) не включает очистку буфера хранилища.
Это похоже на описание Preshing в Барьеры памяти похожи на операции управления исходным кодом., где препятствия StoreStore не возникают мгновенно. Позже в этой статье он объясняет, почему барьер #StoreStore + #LoadLoad + #LoadStore не суммируется с барьером #StoreLoad. (x86 LFENCE имеет некоторую дополнительную сериализацию потока инструкций, но, поскольку он не очищает буфер хранилища, рассуждения все еще остаются в силе).
LFENCE не полностью сериализуется, как cpuid
( который является таким же сильным барьером памяти, как mfence
или lock
ed инструкция). Это просто барьер LoadLoad + LoadStore плюс некоторые вещи сериализации выполнения, которые, возможно, начинались как деталь реализации, но теперь закреплены в качестве гарантии, по крайней мере, для процессоров Intel. Это полезно с rdtsc
, а также для предотвращения спекуляций ветвями для смягчения последствий Spectre.
Кстати, SFENCE не работает для магазинов WB (обычных).
Он упорядочивает хранилища WC (например, movnt или записи в видеопамять) в отношении любых хранилищ, но не в отношении нагрузок или LFENCE. Только на ЦП, который обычно слабо упорядочен, барьер магазин-магазин делает что-нибудь для обычных магазинов. Вам не понадобится SFENCE, если вы не используете хранилища NT или область памяти, отображаемую в WC. Если бы он гарантировал очистку буфера хранилища до его выхода из эксплуатации, вы могли бы построить MFENCE из SFENCE + LFENCE, но это не относится к Intel.
Реальная проблема заключается в переупорядочивании StoreLoad между магазином и грузом, а не между магазином и барьерами, поэтому вам следует посмотреть на случай с магазином, затем барьер, затем груз.
mov [var1], eax
sfence
lfence
mov eax, [var2]
может стать глобально видимым (т. е. зафиксировать в кэше L1d) в следующем порядке:
lfence
mov eax, [var2] ; load stays after LFENCE
mov [var1], eax ; store becomes globally visible before SFENCE
sfence ; can reorder with LFENCE
person
Peter Cordes
schedule
14.05.2018
memory controller
. Заборы используются для координации системной памяти и кэш-памяти. И я думаю, что за согласованность кэша отвечаетmemory controller
. - person Peng Zhang   schedule 30.12.2014L/S/MFENCE
не имеет отношения к когерентности кеша, потому чтоSFENCE
очищает буфер хранилища, который не имеет отношения к когерентности кеша. В некоторых процессорах (не x86) Load FENCE flush Invalidate-Queue, но x86 не имеет этого. В Интернете я обнаружил, что LFENCE не имеет смысла в процессорах x86, т.е. ничего не делает. Тогда переупорядочиваниеSFENCE
MOV reg, [addr]
- ›MOV reg, [addr]
SFENCE
возможно только теоретически, а не, возможно, в действительности, правда? - person Alex   schedule 30.12.2014