GCC 4.7.3内置原子函数是否会自动添加必要内存屏障?
关于GCC 4.7.3中__atomic_*函数与__ATOMIC_SEQ_CST内存屏障的疑问解答
首先直接给你结论:你完全可以依赖GCC 4.7.3自动为__ATOMIC_SEQ_CST内存模型的原子操作添加必要的内存屏障或生成符合语义的指令,不需要手动添加额外的屏障。你没看到mfence是因为x86平台的硬件内存特性让部分操作不需要显式屏障,下面详细解释:
1. x86平台的硬件内存模型(TSO)特性
x86处理器遵循**Total Store Order(TSO)**内存模型,它本身就提供了较强的内存顺序保证:
- 同类型操作(加载-加载、存储-存储)不会重排
- 存储操作不会重排到更早的加载操作之前
- 仅允许加载操作重排到更早的、针对不同地址的存储操作之后
而__ATOMIC_SEQ_CST要求所有原子操作形成一个单一的全局执行顺序,在x86平台上,大部分情况下不需要全内存屏障(比如mfence)就能满足这个要求:
- 对于
__atomic_load_n(原子加载):普通的mov指令就已经符合__ATOMIC_SEQ_CST的语义,因为TSO模型保证加载操作的顺序性足够强,不需要额外屏障 - 对于
__atomic_store_n(原子存储):GCC会生成mov+mfence组合,或者使用lock xchg指令(lock前缀本身隐含全内存屏障效果),这时候你就能看到对应的屏障指令 - 对于
__atomic_exchange_n、__atomic_compare_exchange_n等带lock前缀的操作:lock前缀已经自带全内存屏障,所以不需要额外的mfence
2. GCC 4.7.3对内置原子函数的实现保证
根据GCC 4.7的官方文档,其内置的__atomic_*系列函数是严格按照C++11内存模型语义实现的,针对不同目标平台(比如x86)会自动选择最优的指令和屏障组合,来满足指定的内存模型要求。你不需要手动干预——编译器会处理好底层的内存顺序细节。
3. 为什么你的示例没看到mfence?
如果你的测试代码只用到了__atomic_load_n,那没看到mfence是完全正常的,因为x86的加载操作不需要它。你可以试试写一个包含__atomic_store_n(使用__ATOMIC_SEQ_CST)的示例,编译后查看汇编,应该就能看到mfence或者带lock前缀的指令。
另外要注意:GCC的优化不会破坏原子操作的语义,即使开启了-O2等优化级别,编译器也不会移除必要的内存屏障或指令。
内容的提问来源于stack exchange,提问作者user827046
相关产品推荐
相关产品推荐

