Обеспечивают ли заблокированные инструкции барьер между слабо упорядоченными доступами?

На х86, lock-приставленные инструкции, такие как lock cmpxchg обеспечивают семантику барьера в дополнение к их элементарной работе: для нормального доступа к памяти в областях памяти с обратной записью операции чтения и записи не переупорядочиваются lockинструкции с префиксом, согласно разделу 8.2.2 тома 3 Intel SDM:

Чтение или запись не могут быть переупорядочены с помощью инструкций ввода / вывода, заблокированных инструкций или инструкций сериализации.

Этот раздел относится только к типам памяти с обратной записью. В том же списке вы найдете исключение, в котором отмечается, что слабо упорядоченные магазины не упорядочены:

  • Чтения не переупорядочиваются с другими чтениями.
  • Записи не переупорядочиваются со старыми чтениями.
  • Записи в память не переупорядочиваются с другими записями, за следующими исключениями:

    потоковые хранилища (записи), выполняемые с помощью временных инструкций перемещения (MOVNTI, MOVNTQ, MOVNTDQ, MOVNTPS и MOVNTPD); а также -

    строковые операции (см. раздел 8.2.4.1).

Обратите внимание, что нет никаких исключений для невременных инструкций в любых других элементах в списке, например, в элементе, ссылающемся на инструкции с префиксом блокировки.

В различных других разделах руководства упоминается, что mfence и / или sfence инструкции могут использоваться для упорядочения памяти, когда используются слабо упорядоченные (не временные) инструкции. Эти разделы обычно не упоминают lockинструкция с префиксом в качестве альтернативы.

Все, что оставляет меня неуверенным: делать lockинструкции с префиксом обеспечивают тот же полный барьер, что mfence обеспечивает между слабо упорядоченными (не временными) инструкциями в памяти WB? Тот же вопрос применяется снова, но к любому типу доступа к памяти WC.

2 ответа

Инструкции с префиксом блокировки более мощные, чем у Intel mfence, AMD64-х mfence является полностью сериализованной инструкцией, поэтому она строго сильнее инструкций с префиксом Lock. Есть также 32-битные процессоры AMD x86, которые поддерживают 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:

Все предыдущие загрузки и сохранения завершаются в памяти или пространстве ввода / вывода до того, как будет выпущен доступ к памяти для команды ввода / вывода, блокировки или сериализации.

Все загрузки и сохранения, связанные с командами ввода-вывода и заблокированными, завершаются в памяти (без буферизованных хранилищ) до выдачи загрузки или сохранения из последующей инструкции.


Эксперименты @PeterCordes показывают, что в Skylake инструкции по блокировке, по-видимому, не блокируют выполнение команд ALU во время mfence сериализует инструкции ALU (потенциально ведет себя идентично lfence + очистка буфера хранилища как заблокированная инструкция).

Автобусные замки (через LOCK префикс opcode) создает полный забор *, однако для памяти WC они не обеспечивают ограничение нагрузки, это задокументировано в Руководстве разработчика программного обеспечения для архитектуры Intel 64 и IA-32, том 3A, 8.1.2:

Для процессоров семейства P6 заблокированные операции сериализуют все невыполненные операции загрузки и сохранения (то есть ожидают их завершения). Это правило также справедливо для процессоров Pentium 4 и Intel Xeon, за одним исключением. Операции загрузки, которые ссылаются на слабо упорядоченные типы памяти (например, тип памяти WC), могут быть не сериализованы.

* Для примера см. Руководство разработчика программного обеспечения для архитектуры Intel 64 и IA-32, том 3A, 8.2.3.9.

Другие вопросы по тегам