X86平台原子操作性能对比及RMW操作存储缓冲区技术问询
原子操作性能与内存模型问题解答
问题1:X86平台上load(memory_order_seq_cst)与atomic_fetch_add(0, memory_order_relaxed)哪个性能更优?
atomic_fetch_add(0, memory_order_relaxed)本质是带lock前缀的RMW(读-改-写)操作,即使加0,也会执行“读取内存值→无修改→写回内存”的完整原子流程,lock前缀会触发缓存锁定或总线锁定,带来显著性能开销。
而load(memory_order_seq_cst)在X86平台上等价于普通的mov加载指令(X86的TSO内存模型天然保证load不会被重排到后续store之后,seq_cst的全局顺序约束对单load操作的性能几乎无影响),仅需读取缓存/内存,没有lock前缀带来的额外开销。
结论:load(memory_order_seq_cst)性能更优。
问题2:计数变量的两种实现方案,哪种性能更优?
方案1
// Read aaa.fetch_add(0, memory_order_relaxed); // Write aaa.fetch_add(1, memory_order_relaxed);
方案2
// Read aaa.load(memory_order_seq_cst); // Write aaa.fetch_add(1, memory_order_seq_cst);
性能对比分析:
- 读操作:方案1的
fetch_add(0, relaxed)是带lock前缀的RMW操作,开销极大;方案2的load(seq_cst)是普通mov加载,开销极小。 - 写操作:X86平台上,原子RMW操作(无论
relaxed还是seq_cst语义)都必须使用lock前缀,因此两种方案的写操作开销几乎一致。
结论:方案2性能更优。
问题3:线程T1的storebuffer中存在变量aaa时,T1的原子RMW操作会刷新整个storebuffer吗?
不会刷新整个storebuffer。
X86平台上,原子RMW操作(带lock前缀)仅会确保:线程T1对变量aaa的未提交写入(即storebuffer中与aaa相关的条目)被优先提交到缓存,然后基于该地址的最新值执行RMW操作。对于storebuffer中其他无关变量的未提交写入,不会被强制刷新。
内容的提问来源于stack exchange,提问作者likecpp
相关产品推荐
相关产品推荐

