原子上更新最大值

updating maximum value atomically

本文关键字:最大值 更新      更新时间:2023-10-16

以下代码是更新原子变量的最大值的正确实现吗?std::memory_order_relaxed的使用是否正确,失败正确且最佳?

template<typename T>
inline void update_max(std::atomic<T> & atom, const T val)
{
  for(T atom_val=atom;
      atom_val < val &&
      !atom.compare_exchange_weak(atom_val, val, std::memory_order_relaxed);
     );
}

请注意,这个问题基本上解决了相同的问题(尽管在特定的上下文中(,但是(接受的(答案不是结论性的,特别是关于记忆顺序,(并且可能已过时(。

<</p>

用线程安全方式更新最大值的策略是正确的。

由于您未显示的代码,内存排序是否正确。如果除了报告值(即对其他内存操作的依赖关系(以外的任何上下文中都没有使用原子最大值,则您可能会逃脱std::memory_order_relaxed

正如我在评论中提到的那样,在X86上,编译器可能会产生相同的装配说明,而不管使用内存订购参数如何。 X86是一个强烈订购的CPU,这意味着(默认情况下(不允许#LoadLoad#LoadStore重新排序。因此,您找不到(理智的(编译器,该编译器会在seq_cst load周围发出内存围栏。(默认情况下,#StoreLoad仍允许重新排序,但是为了防止seq_cst排序的订购,通常在store侧处理(。

至于compare_exchange_weak(一个读取模式 - 工具(,这需要锁定缓存线才能为原子;您将在X86上看到这些汇编说明:lock cmpxchg
由于这也是一个完整的内存障碍,因此消除了对其他围栏的需求。

请注意,如果您在任何原子操作上使用std::memory_order_relaxed,则编译器仍然可以自由应用编译时间重新排序