Похоже, часть того, что вы на самом деле спрашиваете:
Почему не lock
префикса неявного для cmpxchg
с операндом памяти, like it is for xchg
?
Простой ответ (что другие дали) - это просто, что Intel разработала его таким образом. Но это приводит к вопросу:
Почему Intel это сделала? Есть ли прецедент для cmpxchg
без lock
?
На однопроцессорной системе, cmpxchg
является атомных по отношению к другим потокам, или любой другой код, работающий на одном ядре процессора. (Но не для «системных» наблюдателей, таких как устройство ввода-вывода с памятью или устройство, которое DMA считывает нормальную память, поэтому lock cmpxchg
имеет значение даже для однопроцессорных схем процессора).
Контекстные коммутаторы могут выполняться только на прерываниях, а прерывания происходят до или после инструкции, а не в середине. Любой код, запущенный на том же CPU, будет видеть, что cmpxchg
либо полностью выполнен, либо вообще нет.
Например, ядро Linux обычно компилируется с поддержкой SMP, поэтому он использует lock cmpxchg
для атомной CAS. Но при загрузке в однопроцессорной системе он исправляет префикс lock
до nop
везде, где этот код был встроен, поскольку nop
cmpxchg
работает намного быстрее, чем lock cmpxchg
. Для получения дополнительной информации см. Это LWN article about Linux's "SMP alternatives" system. Он может даже заплатить до lock
префиксов перед подключением второго процессора.
Подробнее о атомарностью отдельных инструкций по однопроцессорных систем in this answer, и в @supercat's answer + comments на Can num++
атомарные для int num
. См. my answer there для получения подробной информации о том, как атомичность действительно работает/реализована для инструкций read-modify-write, таких как lock cmpxchg
.
(Это же рассуждение относится и к cmpxchg8b
/cmpxchg16b
и xadd
, который обычно используется только для Synchonization/атомных опсов, а не делать однопоточные коды работать быстрее. Очевидно, что память назначение add [mem], reg
полезен вне lock add [mem], reg
кейс.)
Очевидно, вы можете использовать адрес памяти, вот и все. Первый операнд имеет тип r/m, так что вы идете. И как вы могли бы префикс инструкции с помощью 'lock', если бы она сама не существовала? – harold
@harold Я не совсем понимаю, чего не существует. Вы префикс LOCK, если вы хотите, чтобы команда была атомарной. Итак, CMPXCHG, без префикса LOCK, является атомарным или нет? –
Нет, но в вашем вопросе 2 вы, кажется, спрашиваете, почему существует «cmpxchg без блокировки», что является нечетным, поскольку комбинация не может существовать без частей - если это не то, что вы имели в виду, тогда вы можете уточнить? – harold