Все перечисленное подразумевает 64-битную архитектуру x86_64.Я считаю, что в целом то, о чем вы просили, невозможно на 32-битной x86.
На самом деле есть два варианта.Первым является _InterlockedCompareExchange128
, что означает LOCK CMPXCHG16B
.Чтобы дублировать функциональность 16-байтового хранилища с ним, вам нужно сделать что-то вроде этого:
__int64* dest = ...;
__int64* orig = ...;
unsigned char ok;
do
{
__int64 high = dest[0];
__int64 low = dest[1];
ok = _InterlockedCompareExchange128(dest, high, low, orig);
}
while (!ok);
Обратите внимание, что, поскольку это операция с блокировкой, она подразумевает эквивалент _ReadWriteBarrier
.Обычно это то, что подразумевается под «атомарной» операцией.
Если вы хотите чистый магазин, а не обмен сравнения, тогда вы можете использовать все, что преобразуется в согласованное 16-байтовое хранилище на оборудовании.Например, инструкция MOVDQA
будет соответствовать.В C ++ это выглядело бы примерно так:
__m128i* dest = ...;
_mm_mfence();
_mm_store_si128(dest, _mm_loadu_si128((__m128i*)&orig));
_mm_mfence();
Если у вас нет причин избегать инструкций SSE, я думаю, что вторая версия может работать лучше.Вы также можете решить, хотите ли вы ослабить два барьера памяти в зависимости от ваших реальных потребностей.