Инструкции с префиксом блокировки строго более мощные, чем у Intel mfence
1 .AMD64 mfence
является полностью сериализованной инструкцией, поэтому она строго сильнее инструкций с префиксом Lock.Есть также 32-битные x86 процессоры AMD , которые поддерживают mfence
, и я ожидаю, что он ведет себя так же, как на AMD64.Остальная часть этого ответа относится только к Intel mfence
.
mfence
, который непосредственно предшествует или следует за инструкцией с префиксом блокировки, является избыточным.Из Раздела 8.2.5:
Инструкции ввода / вывода, инструкции по блокировке, префикс LOCK и инструкции по сериализации усиливают упорядочение процессора.
(Инструкции по блокировкездесь упоминаются неявные lock
. В другом месте руководства они также относятся к инструкциям с явным префиксом lock
.)
«сильнее» здесь означает более сильный, чем порядок по умолчанию, описанный в разделе 8.2.2.(цитируется в вопросе).Также из 8.2.5:
Как и команды ввода-вывода и блокировки, процессор ожидает выполнения всех предыдущих инструкций и всех буферизованных записей в память перед выполнением команды сериализации.
В разделе 8.3 обсуждаются команды сериализации, в которых вообще не упоминается префикс блокировки.Но это говорит об этом:
Следующие инструкции являются инструкциями по упорядочению памяти, а не инструкциями по сериализации.Они истощают подсистему памяти данных.Они не сериализуют поток выполнения инструкций:
• Непривилегированные команды упорядочения памяти - SFENCE, LFENCE и MFENCE.
Важно отметить, что префикс блокировки несоздать сериализованную инструкцию, подобную тем, которые перечислены в разделе 8.3.Основное отличие состоит в том, что префикс блокировки позволяет получить следующие инструкции.Кроме того, инструкция с заблокированным префиксом не упорядочена в отношении инструкций предварительной выборки программного обеспечения.Из руководства Intel V2:
Инструкция PREFETCHh считается намеком на это умозрительное поведение.Поскольку эта умозрительная выборка может происходить в любое время и не связана с выполнением инструкций, команда PREFETCHh не упорядочена относительно команд ограничения (MFENCE, SFENCE и LFENCE) или заблокированных ссылок на память.Инструкция PREFETCHh также неупорядочена относительно инструкций CLFLUSH и CLFLUSHOPT, других инструкций PREFETCHh или любых других общих инструкций.Он упорядочен в отношении инструкций сериализации, таких как CPUID, WRMSR, OUT и MOV CR.
То же самое относится ко всем инструкциям предварительной выборки программного обеспечения, а не только PREFETCHh
.
Что делает префикс блокировки более мощным, чем mfence
, так это то, что он не только обеспечивает сериализацию всех инструкций (кроме программной предварительной выборки), но также блокирует доступ к разделяемой памяти, так что все другие логические процессоры не могут получить доступ к памяти, пока она не выйдет из строя,тем самым обеспечивая атомарность.
Теперь я видел цитату из ответа Некролиса, в которой говорится, что префикс блокировки может не сериализовать операции загрузки, которые ссылаются на слабо упорядоченные типы памяти.Но я думаю, что это утверждение очень старое и написано для очень старых процессоров в то время, когда Intel не хотела предоставлять полные гарантии префикса блокировки.Кроме того, в цитате говорится только «возможно, нет», что на самом деле не противоречит.
Это также можно подтвердить из руководства AMD V2 7.4.2:
Все предыдущие загрузки ихранит заполненные в памяти или пространстве ввода / вывода до того, как будет выполнен доступ к памяти для ввода / вывода, заблокирована или инструкция сериализации.
Все загрузки и сохранения, связанные с инструкциями ввода / вывода и заблокированными, завершены в памяти (нетбуферизованные хранилища) перед загрузкой или сохранением из последующей инструкции.
Сноски: (1)Похоже, что в Haswell, Ivy Bridge, Sandy Bridge и потенциально более ранних микроархитектурах есть ошибка, при которой инструкция с префиксом блокировки не может сериализовать загрузки NT, а MFENCE
может. На Skylake обе инструкции не могут сериализовать загрузку NT. См .: Имеет ли блокировка xchg то же поведение, что и mfence? . Однако на Broadwell и процессорах после Skylake оказалось, что обе инструкции могут сериализовать загрузки NT.
@ * Эксперименты PeterCordes показывают, что на Skylake инструкции по блокировке, по-видимому, не блокируют выполнение команд ALU из-за неправильного порядка, в то время как mfence
сериализует инструкции ALU (потенциально ведущие себя идентично lfence
+ очистка буфера хранилища как заблокированная инструкция). Тем не менее, я думаю, что это деталь реализации.