是否有Windows API以原子方式设置16字节数组?

时间:2012-03-24 04:37:35

标签: c++ multithreading winapi atomic

我想知道是否有一个Windows API来原子地设置一个16字节的数组?

我真的很讨厌将关键部分或互斥体引入这个实现这个操作,所以我试图找到一个更简单的解决方案。

PS。我需要这个,因为这个16字节的数组可以从工作线程写入,并且主要从主线程中读取。

1 个答案:

答案 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指令,否则我认为第二版可能表现更好。您可能还想根据实际需要决定是否要放宽两个记忆障碍。