C++ 原子加载排序效率

标签 c++ c++11 atomic

我有一个内存变量,它在线程 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 不同的唯一方法是阻止某些编译器优化。

关于C++ 原子加载排序效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13483150/

相关文章:

c++ - 为什么 std::vector 调整大小失败?

c++ - std::transform 中的二元运算符,带有 unique_ptr 的 vector

c++ - 为什么这个C++程序编译失败?

cocoa - NSObject的retain方法是原子的吗?

java - 原子整数 lazySet 性能提升

java - 当仅使用 get() 和 set() 方法时,将 AtomicBoolean 替换为原始类型?

c++ - 评论 : reusable safe_bool implementation

c++ - 我如何检查在无模式对话框中单击了该按钮

java - Java 和 C++ 的对象

c++ - 为什么 std::is_function<T> 会导致编译错误?