atomic_thread_fence(memory_order_seq_cst)总是产生一个完整的障碍。
- x86_64:
MFENCE
- 电源电脑:
hwsync
- 伊塔努伊姆:
mf
- ARMv7 / ARMv8:
dmb ish
- MIPS64:
sync
主要的事情:观察线程可以简单地以不同的顺序观察,与你在观察线程中使用什么栅栏无关。
优化编译器是否允许将指令 (3) 重新排序到 (1) 之前?
不,这是不允许的。但是对于多线程程序来说,这是全局可见的,只有在以下情况下才是正确的:
- 其他线程对
memory_order_seq_cst具有这些值的原子读/写操作使用相同的
- 或者如果其他线程
atomic_thread_fence(memory_order_seq_cst);在 load() 和 store() 之间也使用相同的 - 但这种方法通常不能保证顺序一致性,因为顺序一致性是更强有力的保证
工作草案,编程语言 C++ 标准 2016-07-12:http ://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf
§ 29.3 秩序和一致性
§ 29.3 / 8
[注意:memory_order_seq_cst 仅确保没有数据竞争且仅使用 memory_order_seq_cst 操作的程序的顺序一致性。除非非常小心,否则任何使用较弱的排序都会使此保证失效。特别是,memory_order_seq_cst 栅栏仅确保栅栏本身的总顺序。通常,栅栏不能用于恢复具有较弱排序规范的原子操作的顺序一致性。——尾注]
如何将其映射到汇编程序:
情况1:
atomic<int> x, y
y.store(1, memory_order_relaxed); //(1)
atomic_thread_fence(memory_order_seq_cst); //(2)
x.load(memory_order_relaxed); //(3)
此代码并不总是等同于 Case-2 的含义,但此代码在 STORE 和 LOAD 之间以及 LOAD 和 STORE 都使用时产生相同的指令memory_order_seq_cst- 这是防止 StoreLoad-reordering 的顺序一致性,Case-2:
atomic<int> x, y;
y.store(1, memory_order_seq_cst); //(1)
x.load(memory_order_seq_cst); //(3)
附上一些注释:
- 它可能会添加重复的指令(如下面的 MIPS64 示例)
或者可以以其他指令的形式使用类似的操作:
- 与 x86_64 的替代 3/4 映射一样,-prefix
LOCK完全刷新 Store-BufferMFENCE以防止 StoreLoad 重新排序
- 或 ARMv8 - 我们知道,这
DMB ISH是阻止 StoreLoad 重新排序的全屏障:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/ CHDGACJD.html
ARMv8-A 指南
表 13.1。屏障参数
ISH任意 - 任意
Any - Any 这意味着加载和存储都必须在屏障之前完成。在程序顺序中出现在屏障之后的加载和存储都必须等待屏障完成。
可以通过这两条指令之间的附加指令来防止两条指令的重新排序。正如我们看到的第一个 STORE(seq_cst) 和下一个 LOAD(seq_cst)生成指令之间的指令与 FENCE(seq_cst) ( atomic_thread_fence(memory_order_seq_cst))
C/C++11memory_order_seq_cst到不同 CPU 架构的映射:load(), store(), atomic_thread_fence():
注意atomic_thread_fence(memory_order_seq_cst); 总是生成全屏障:
x86_64:MOV (into memory),MFENCE存储- ,加载- MOV (from memory),围栏-MFENCE
x86_64-alt:存储- MOV (into memory),加载-,围栏-MFENCE,MOV (from memory)MFENCE
x86_64-alt3: STORE- (LOCK) XCHG, LOAD- MOV (from memory), fence- MFENCE-全屏障
x86_64-alt4: STORE- MOV (into memory), LOAD- LOCK XADD(0), fence- MFENCE-全屏障
PowerPC: STORE- hwsync; st、 LOAD- 、 fence-hwsync;ld; cmp; bc; isynchwsync
安腾:STORE- st.rel;mf、 LOAD- ld.acq、 fence-mf
ARMv7:dmb ish; str;dmb ish存储- ,加载- ldr; dmb ish,围栏-dmb ish
ARMv7-alt:存储- dmb ish; str、加载-、围栏-dmb ish;ldr; dmb ishdmb ish
ARMv8(AArch32): STORE- STL, LOAD- LDA, fence- DMB ISH-全屏障
ARMv8(AArch64): STORE- STLR, LOAD- LDAR, fence- DMB ISH-全屏障
MIPS64: STORE- sync; sw;sync;、 LOAD- sync; lw; sync;、 fence-sync
描述了 C/C++11 语义到不同 CPU 架构的所有映射:load()、store()、atomic_thread_fence():http ://www.cl.cam.ac.uk/~pes20/cpp/ cpp0xmappings.html
因为 Sequential-Consistency 阻止了 StoreLoad-reordering,并且因为 Sequential-Consistency (store(memory_order_seq_cst)和 next load(memory_order_seq_cst)) 在其之间生成的指令与 相同atomic_thread_fence(memory_order_seq_cst),所以atomic_thread_fence(memory_order_seq_cst)阻止了 StoreLoad-reordering。