C++原子负载排序效率

C++ atomic load ordering efficiency

本文关键字:排序 效率 负载 C++      更新时间:2023-10-16

我有一个内存变量,它在线程a中更新,并在其他线程中读取。读取器只关心该值是否为非零。我保证,一旦值增加,它就永远不会回到零。按以下方式进行优化有意义吗?换句话说,在读者方面,一旦我的条件得到满足,我就不需要"围栏"了。

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);
}

首先,如果您还没有真正尝试使用默认的(顺序一致的)原子,测量应用程序的性能,对其进行分析,并观察到它们导致性能问题,我建议现在就回头。

然而,如果你真的需要开始对宽松的原子论进行推理。。。


尽管它几乎肯定会在x86上运行,但这并不能保证达到您的预期。

我猜您是在使用它来保护其他一些非原子数据的发布。

在这种情况下,您需要保证如果您在读取器线程中读取了一个非零值,在存储之前在编写器线程中对非原子内存位置产生的各种其他副作用(即初始化您正在发布的数据)将对读取器线程可见。

std::memory_order_relaxed读取非零不会std::memory_order_release存储同步,因此您上面的代码没有此保证。

要获得我所描述的行为,您需要使用std::memory_order_acquire。如果您使用的是x86,那么acquire不会生成任何内存围栏指令,因此它与memory_order_relaxed在性能上不同的唯一方法是阻止一些编译器优化。