atomic_compare_exchange со значением «больше» вместо «равно»?

В C ++ 11 есть операция сравнения и обмена для атомные переменные.

Семантика:

Атомно сравнивает значение, на которое указывает obj со значением, указанным expectedи если это равный, заменяет первое с desired (выполняет операцию чтения-изменения-записи). В противном случае загружает фактическое значение, на которое указывает obj в *expected (выполняет операцию загрузки).

Я хочу сделать то же самое, но вместо установки *obj когда значения равны, я хочу, чтобы он был установлен, когда один лучше чем другой (предположим, мы говорим о упорядоченном типе).

Это как-то поддерживается? Достижимо ли это каким-то взломом?

Замечания: Цикл CAS не подходит для меня, так как оба сравниваемых значения могут меняться между неатомарными операциями.

5

Решение

По запросу, вот мой комментарий в качестве ответа:


Я тоже хотел бы, чтобы это существовало, но, насколько я знаю, этого не происходит (конечно, не для x86 / x64), кроме концептуально, конечно, и обходных путей, которые (потенциально) используют более одной атомарной инструкции (которая работает но не без ожидания).

3

Другие решения

Я думаю, что вы неправильно понимаете, как работает сравнение и обмен / обмен: основная идея состоит в том, что, посмотрев на текущее значение, вы можете получить какое-то соответствующее новое значение — и вы пытаетесь это обновить. Если это удастся — отлично — продолжайте с тем, что вам нужно, но если это не удастся, начните все сначала: посмотрите на новое значение, которое вставил какой-то другой поток, и подумайте о значении, которое вам, следовательно, теперь потребуется.

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

Допустим, вы хотите сохранить 11, но только если существующее значение по-прежнему атомарно меньше 11. Вы не найдете инструкции, чтобы сделать это напрямую, но вы можете легко сделать это с существующим сравнением и обменом:

int target_value = 11;
do {
int snapped_x = x;
if (snapped_x >= target_value)
what do you want to do instead?
} while (!compare_and_swap(x, snapped_x, target_value));
// ...or whatever your exact calling convention is...

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

5

По вопросам рекламы [email protected]