C++原子操作内存序与显式内存栅栏等价性的疑问及相关场景求证
C++原子操作内存序与显式内存栅栏等价性的疑问及相关场景求证
我最近在琢磨C++原子操作的内存序和显式内存栅栏的关系,有个猜想想跟各位大佬探讨:是不是所有原子操作的内存序约束,都能拆解成对应的relaxed原子操作加上显式的内存栅栏(忽略已经废弃的consume序)?
我自己做了个测试,写了两个函数:
#include <atomic> std::atomic<int> i; bool f1(int e, int v) { // 默认使用memory_order_seq_cst的compare_exchange_strong return i.compare_exchange_strong(e, v); } bool f2(int e, int v) { std::atomic_thread_fence(std::memory_order_seq_cst); // 用relaxed版本的原子操作,前后包裹seq_cst栅栏 bool res = i.compare_exchange_strong(e, v, std::memory_order_relaxed); std::atomic_thread_fence(std::memory_order_seq_cst); return res; }
把这两段代码在弱序架构下编译后,生成的汇编完全一样。这让我更倾向于认为这个猜想是对的——结合原子变量操作和显式栅栏的做法,好像并不是必须的?
不过我还是有点拿不准,想请教大家几个问题:
- 有没有实际的代码示例或者场景,能证明这个猜想不成立?也就是说,存在某种情况,直接使用带指定内存序的原子操作,和用relaxed操作加显式栅栏的行为不一致?
- 针对强序的目标架构,编译器的优化器是不是很难自动消除源码中冗余的显式栅栏?
- 如果这个猜想确实成立,那要是cppreference把原子操作的内存序都拆解成relaxed操作加显式栅栏来讲解,会不会更容易理解?毕竟现在原子操作自带的内存序和显式栅栏的规则有重叠,分开讲的话逻辑会更清晰简洁,内容也更紧凑。
内容来源于stack exchange
相关产品推荐
相关产品推荐

