我想知道是否有一个Windows API来原子地设置一个16字节的数组?
我真的很讨厌将关键部分或互斥体引入这个实现这个操作,所以我试图找到一个更简单的解决方案。
PS。我需要这个,因为这个16字节的数组可以从工作线程写入,并且主要从主线程中读取。
答案 0 :(得分:4)
以下所有内容均假定采用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指令,否则我认为第二版可能表现更好。您可能还想根据实际需要决定是否要放宽两个记忆障碍。