x86架构下原子操作的fail memory_order是否具备实际意义?
关于atomic_compare_exchange_strong_explicit中memory_order fail的疑问
先来看atomic_compare_exchange_strong_explicit的定义:
_Bool atomic_compare_exchange_strong_explicit( volatile A* obj, C* expected, C desired, memory_order succ, memory_order fail );
我对其中memory_order fail的使用场景感到困惑。针对x86架构,lock cmpxchg可能执行失败是明确的,但x86有明确规定:
读取或写入操作不能与I/O指令、锁定指令或序列化指令重排序
这使得memory_order fail似乎无关紧要,因为lock指令在任何情况下都保证顺序一致性。
示例代码
#include <stdatomic.h> void fail_seqcst(volatile int *p, int *expected, int *desirable){ atomic_compare_exchange_strong_explicit(p, expected, desirable, memory_order_release, memory_order_seq_cst); } void fail_relaxed(volatile int *p, int *expected, int *desirable){ atomic_compare_exchange_strong_explicit(p, expected, desirable, memory_order_release, memory_order_relaxed); }
编译结果
fail_relaxed: mov ecx, edx mov eax, DWORD PTR [rsi] lock cmpxchg DWORD PTR [rdi], ecx mov DWORD PTR [rsi], eax sete al movzx eax, al ret fail_seqcst: mov ecx, edx mov eax, DWORD PTR [rsi] lock cmpxchg DWORD PTR [rdi], ecx mov DWORD PTR [rsi], eax sete al movzx eax, al ret
问题
- 在x86架构下,编译器是否会针对
memory_order_relaxed和memory_order_seq_cst生成差异化的代码? - 是否存在其他架构会让这两者的差异变得显著?
解答
x86架构下不会生成差异化代码
从给出的编译结果可以看到,两个函数对应的汇编指令完全一致。这是因为x86的lock前缀指令本身就强制了全局内存顺序一致性,无论CAS失败时指定的是memory_order_relaxed还是memory_order_seq_cst,lock指令的硬件特性已经覆盖了这些内存序的要求,编译器无需额外生成不同指令。弱内存模型架构会体现显著差异
像ARM、PowerPC这类弱内存模型的架构,没有x86那样严格的内存序保证。当CAS操作失败时,memory_order fail的参数会直接影响编译器生成的内存屏障指令:
- 若指定
memory_order_seq_cst,编译器会插入全内存屏障(例如ARM的dmb ish),确保失败后的内存操作不会与CAS的读取部分重排序; - 若指定
memory_order_relaxed,编译器不会插入任何额外屏障,允许失败后的内存操作与CAS的读取部分重排序,以此换取更好的性能表现。
内容的提问来源于stack exchange,提问作者Some Name
相关产品推荐
相关产品推荐

