You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多线程操作std::atomic<int>自增时的最优内存序选择及原理问询

原子计数的最优内存序:memory_order_relaxed的正确打开方式

先直接给结论:对于你这种多线程原子计数的场景,memory_order_relaxed就是最优选择——它既能保证计数完全正确,又能带来最高的执行效率。

你之所以会担心出现那种"两个线程先load同一个值,加1后再覆盖写入"的情况,核心是误解了fetch_add的本质:它不是拆分开的load、add、store三个独立操作,而是一个原子的读-修改-写(RMW)操作。不管用什么内存序,硬件都会保证这个RMW操作是不可分割的——也就是说,线程1的fetch_add要么完整地完成"读当前Num值→加1→写回新值"的全流程,要么线程2的fetch_add先完成,绝对不会出现你脑补的那种交叉执行的情况。

那memory_order_relaxed到底放松了什么?它确实不会对其他读/写操作施加同步或排序约束,但这只影响这个原子操作和线程中其他非原子操作的相对顺序,完全不影响原子操作本身的原子性。举个例子:如果你的线程里除了Num.fetch_add(1),还有其他变量的读写,relaxed允许编译器和CPU重排这些操作的顺序,但对于Num的计数来说,每个fetch_add都是独立且原子的累加,最终的结果一定是准确的线程调用次数总和。

对比默认的memory_order_seq_cst,它会强制所有线程看到的全局操作顺序一致,相当于给整个系统加上了一个全局的"内存屏障",这在很多架构上会带来额外的性能开销。但对于简单的计数场景,我们根本不需要这种全局一致性——我们只关心每个计数被正确累加,不关心不同线程的其他操作谁先谁后。relaxed跳过了这些不必要的同步约束,所以是效率最高的选择。

总结一下:

  • memory_order_relaxed保留了原子RMW操作的核心原子性,确保计数不会被覆盖
  • 它去掉了不必要的全局内存顺序约束,让编译器和CPU可以做更多优化,性能最优
  • 你担心的执行序列不可能发生,因为fetch_add是不可分割的原子操作

内容的提问来源于stack exchange,提问作者Timur Yalymov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 21:42:44