我有一个在线程A中更新并在其他线程中读取的内存变量。读者只关心值是否为非零。我保证一旦值增加,它就永远不会回到零。 优化如下是否有意义? 换句话说,在读者方面,我不需要" fence"一旦我的病情满意。
std::atomic<int> counter;
writer:
increment()
{
counter.store(counter+1, std:memory_order_release)
}
reader:
iszero()
{
if (counter.load(std::memory_order_relaxed) > 0) return false;
// memory fence only if condition not yet reached
return (counter.load(std::memory_order_acquire) == 0);
}
答案 0 :(得分:2)
首先,如果你没有真正尝试使用默认(顺序一致)原子,测量你的应用程序的性能,分析它,并显示它们导致性能问题,我建议现在回头。
然而,如果你真的需要开始关于放松原子的推理......
虽然它几乎肯定会在x86上运行,但不能保证能达到预期效果。
我猜你正在使用它来保护其他一些非原子数据的发布。
在这种情况下,您需要保证 if 在读者线程中读取非零值,然后对非原子性记忆的各种其他副作用您在商店之前在编写器线程中创建的位置(即初始化您正在发布的数据)将对读者线程可见。
使用std::memory_order_relaxed
读取非零并不会与<{em> std::memory_order_release
商店同步,因此上面的代码没有此保证。
要获得我所描述的行为,您需要使用std::memory_order_acquire
。如果您使用的是x86,那么acquire不会产生任何内存栅栏指令,因此它与memory_order_relaxed
的性能差异的唯一方法是阻止某些编译器优化。