nem*_*equ 7 c atomic interlocked visual-c++
TL;DR:我需要相当于 C11 的 Microsoft C(不是 C++)atomic_load。有谁知道正确的功能是什么?
我有一些使用原子的非常标准的代码。就像是
do {
bar = atomic_load(&foo);
baz = some_stuff(bar);
} while (!atomic_compare_exchange_weak(&foo, &bar, baz));
Run Code Online (Sandbox Code Playgroud)
我想弄清楚如何用 MSVC 处理它。CAS 很简单 ( InterlockedCompareExchange),但atomic_load事实证明更麻烦。
也许我遗漏了一些东西,但MSDN上的同步函数列表似乎没有任何简单加载的东西。我唯一能想到的就是这样的东西InterlockedOr(object, 0),它会为每个负载生成一个商店(更不用说围栏了)……
只要变量是可变的,我认为只读取值是安全的,但是如果我这样做,Visual Studio 的代码分析功能会发出一堆C28112警告(“通过互锁函数访问的变量 (foo) 必须始终可以通过互锁功能访问。”)。
如果简单的阅读真的是正确的方式,我想我可以用类似的东西让那些人沉默
#define atomic_load(object) \
__pragma(warning(push)) \
__pragma(warning(disable:28112)) \
(*(object)) \
__pragma(warning(pop))
Run Code Online (Sandbox Code Playgroud)
但是分析器坚持我应该始终使用这些Interlocked*函数,这让我相信一定有更好的方法。如果是这样,那是什么?
我认为这里忽略分析器是可以接受的,因为文档说寄存器宽度变量的简单读取是安全的(32 位系统上的 32 位,64 位系统上的 64 位)。警告文档本身基本上说它过于谨慎,即使访问可能是安全的。
也就是说,如果你想关闭它,你总是可以使用幂等Interlocked操作来获得所需的行为。例如,您可以定义:
#define atomic_load(object) InterlockedOr((object), 0)
Run Code Online (Sandbox Code Playgroud)
由于按位或 with0永远不会更改该值,并且它始终返回原始值,因此最终结果是读取原始值,同时原子地不写入任何内容。
如果你是模拟atomic_load_explicit与memory_order_relaxed您可以通过使用获得更好的性能InterlockedOrNoFence,以避免内存的障碍,但对于模拟的默认(顺序一致)atomic_load你想坚持InterlockedOr。
InterlockedOr大部分是任意选择的(理论上它在硬件上可能比加法或减法之类的进位运算略快),但是InterlockedXor0 的行为应该与其他几个操作相同,只要它们是用他们的身份价值。
您也可以InterlockedCompareExchange以类似的方式使用;需要测试来确定哪个更快:
#define atomic_load(object) InterlockedCompareExchange((object), 0, 0)
Run Code Online (Sandbox Code Playgroud)
同样,如果该值已经为 0,则将其设置为零,但您真正使用它的目的只是获取返回值,即无操作交换之前的原始值。
| 归档时间: |
|
| 查看次数: |
2337 次 |
| 最近记录: |