Обеспечивают ли заблокированные инструкции барьер между слабо упорядоченными доступами? - PullRequest
0 голосов
/ 10 мая 2018

В x86 инструкции с префиксом 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 ]

0 голосов
/ 12 мая 2018

Инструкции с префиксом блокировки строго более мощные, чем у 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 + очистка буфера хранилища как заблокированная инструкция). Тем не менее, я думаю, что это деталь реализации.

0 голосов
/ 11 мая 2018

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

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

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

...