lock cmpxchg
является атомным;во время его выполнения ничего не может произойти (во всяком случае, логически).В отличие от реализации LL / SC compare_exchange_weak
, он не может внезапно завершиться сбоем, когда другой поток пишет в той же строке кэша, только если сравнение на самом деле не удается.( Может ли CAS дать сбой для всех потоков? )
compare_exchange_strong
может быть реализовано как lock cmpxchg
без цикла.
Вы спрашиваете осценарий использования, когда вы загружаете старое значение, изменяете его, а затем пытаетесь установить новое значение в CAS?(например, для синтеза атомарной операции, которую аппаратное обеспечение не предоставляет напрямую, например, атомарная FP добавляет или атомарный очистить младший бит ).
В этомв случае да, причиной сбоя cmpxchg
будет гонка с другим потоком.
Как объяснил @ ネ ロ ク, вы проверяете результат флага cmpxchg
, чтобы получить логический результат compare_exchange_strong
, т.е.скажите, не прошла ли часть сравнения и было ли выполнено сохранение или нет.См. Ручной ввод Intel для cmpxchg
.
Существуют и другие варианты использования для lock cmpxchg
, например, ожидание появления спин-блокировки при вращении на lock.compare_exchange_weak(0, 1)
, неоднократно пытаясь перевести разблокированную переменную в заблокированное состояние.Таким образом, неисправный CAS не из состояния гонки, он просто из замка все еще удерживается.(Поскольку вы передаете константу как «ожидаемую», а не то, что вы только что прочитали из этого места.)
Как правило, это не очень хорошая идея, AFAIK.Я думаю, что обычно лучше вращать только для чтения в ожидании блокировки, и пытаться взять блокировку только с помощью CAS или XCHG, если вы видели, что она была доступна.(Использование xchg
и проверка целочисленного результата потенциально дешевле, чем lock cmpxchg
, возможно, удерживая строку кэша заблокированной на меньшее количество циклов. Блокирует манипулирование памятью с помощью встроенной сборки )
TL: DR: программирование без блокировки требует прецизионного языка, если вы собираетесь рассуждать о корректности.
cmpxchg
завершается неудачно и очищает ZF (создавая условие ne
не равное), если EAX не соответствуетзначение в памяти, когда оно выполняется.Сама инструкция не знает о гонках и не заботится о них, только о точном состоянии, когда она сама выполняется.
Вам, как программисту, приходится беспокоиться о гонках и повторять попытки при использовании его в качестве строительного блока для создания больших атомарных операций.построен на нем.