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

Is there a Windows API to set 16-byte array atomically?

本文关键字:设置 字节 字节数 数组 方式 Windows API 是否      更新时间:2023-10-16

我想知道是否有一个windows API可以原子地设置16字节数组?

我真的不愿意为了实现这些操作而在其中引入关键部分或互斥,所以我正在努力寻找一个更简单的解决方案。

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

以下所有内容都假定采用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指令,否则我认为第二个版本可能会更好。你可能还想根据自己的实际需求来决定是否要放松这两个记忆障碍。