Intel 64 и IA-32 |Атомарные операции, включая семантику получения / выпуска - PullRequest
6 голосов
/ 27 января 2011

В соответствии с Руководством разработчика программного обеспечения для архитектуры Intel 64 и IA-32 префикс сигнала LOCK «обеспечивает исключительное использование процессором любой совместно используемой памяти, пока подается сигнал».Это может быть в виде блокировки шины или кэша.

Но - и именно поэтому я задаю этот вопрос - мне не ясно, если этот префикс также обеспечивает какой-либо барьер памяти.

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

Итак, нужно ли мне использовать MFENCE,Инструкции SFENCE и LFENCE или это будет излишним?

Ответы [ 3 ]

7 голосов
/ 27 января 2011

Нет, нет необходимости использовать инструкции MFENCE, SFENCE and LFENCE в отношении префикса LOCK.

MFENCE, SFENCE and LFENCE инструкция гарантирует видимость памяти во всех ядрах процессора.Например, инструкция MOV не может использоваться с префиксом LOCK, поэтому, чтобы быть уверенным, что результат перемещения памяти виден всем ядрам ЦП, мы должны быть уверены, что кэш ЦП сброшен в ОЗУ и что мы достигаем с ограждениеминструкции.

РЕДАКТИРОВАТЬ: подробнее о заблокированных атомарных операциях из руководства Intel:

ЗАБЛОКИРОВАННЫЕ АТОМНЫЕ ОПЕРАЦИИ

32-разрядный IA-32Процессоры поддерживают заблокированные атомарные операции над местами в системной памяти.Эти операции обычно используются для управления общими структурами данных (такими как семафоры, дескрипторы сегментов, системные сегменты или таблицы страниц), в которых два или более процессора могут одновременно пытаться изменить одно и то же поле или флаг.Процессор использует три взаимозависимых механизма для выполнения заблокированных атомарных операций:

• Гарантированные атомарные операции

• Блокировка шины с использованием сигнала LOCK # и префикса инструкции LOCK

•Протоколы когерентности кэша, обеспечивающие выполнение атомарных операций над структурами кэшированных данных (блокировка кэша);этот механизм присутствует в процессорах семейства Pentium 4, Intel Xeon и P6

Эти механизмы взаимозависимы в следующих отношениях.Определенные базовые транзакции памяти (такие как чтение или запись байта в системной памяти) всегда гарантированно обрабатываются атомарно.То есть после запуска процессор гарантирует, что операция будет завершена до того, как другому процессору или шинному агенту будет разрешен доступ к ячейке памяти.Процессор также поддерживает блокировку шины для выполнения выбранных операций с памятью (таких как операция чтения-изменения-записи в общей области памяти), которые обычно должны обрабатываться атомарно, но не обрабатываются автоматически таким образом.Поскольку часто используемые области памяти часто кэшируются в кэшах процессора L1 или L2, атомарные операции часто могут выполняться внутри кешей процессора без утверждения блокировки шины.Здесь протоколы когерентности кэша процессора гарантируют, что другие процессоры, которые кэшируют те же самые области памяти, управляются должным образом, в то время как атомарные операции выполняются в областях кэшированной памяти.

4 голосов
/ 31 мая 2013

Из руководств IA32 (том 3A, глава 8.2: Порядок в памяти ):

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

Следовательно, инструкция с ограждением не требуется с заблокированными инструкциями.

0 голосов
/ 02 июня 2018

Проблема по-прежнему возникает при компиляции intel_lock1.c (доступно по адресу выше) в Linux с GCC 5 или 7 без аргументов '-D_WITH_CLFLUSH_' или '-D_WITH_HLE_' (чтобы не использовались ни CLFLUSH *, ни HLE XACQUIRE) - ассемблер mutex_lock теперь выглядит так:

# 74 "intel_lock1.c" 1
    LFENCE
    lock subl   $1, lck(%rip)
    rep nop
    SFENCE

Итак, я пытаюсь заменить {L, S} FENCE на MFENCE.

Я до сих пор не совсем понимаю, как два потока могут иметь одинаковое значение -1 * lck.

...