Является ли AtomicCmpExchange надежным на всех платформах?

Я не могу найти реализацию AtomicCmpExchange (кажется, скрытой), поэтому я не знаю, что он делает.

Является AtomicCmpExchange надежным на всех платформах? Как это внедряется внутри страны? Использует ли он что-то вроде критической секции?

У меня такой сценарий:

MainThread:

Target := 1;

Резьба1:

x := AtomicCmpExchange(Target, 0, 0);

Резьба2:

Target := 2;

Thread3:

Target := 3;

Будет ли x всегда быть целым числом 1, 2 или 3, или это может быть что-то еще? Я имею в виду, даже если AtomicCmpExchange(Target, 0, 0) не удалось обменять значение, возвращает ли оно "действительное" целое число (я имею в виду не целое число с половинным чтением, например, если другой поток уже начал писать половину значения)?

Я хочу избежать использования критического раздела, мне нужна максимальная скорость.

Ответ 1

AtomicCmpExchange - это то, что называется внутренней процедурой или стандартной функцией. Он сам по себе известен компилятору и может иметь или не иметь видимой реализации. Например, Writeln является стандартной функцией, но вы не найдете для нее ни одной реализации. Компилятор разбивает его на несколько вызовов функций нижнего уровня в System.pas. Некоторые стандартные функции, такие как Inc() и Dec(), не имеют реализации в System.pas. Компилятор будет генерировать машинные инструкции, которые составляют простые инструкции INC или DEC.

Подобно Inc() или Dec(), AtomicCmpExchange() реализуется с использованием любого кода, необходимого для данной платформы. Он будет генерировать встроенные инструкции. Для x86/x64 он сгенерирует команду CMPXCHG (вместе с любой настройкой, необходимой для получения переменных/значений в регистры). Для ARM он будет генерировать несколько инструкций вокруг инструкций LDREX и STREX.

Итак, прямой ответ на ваш вопрос заключается в том, что даже вызывая код сборки, вы не можете получить гораздо более эффективную, чем использовать эту стандартную функцию вместе с другими, такими как AtomicIncrement, AtomicDecrement и AtomicExchange.