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; isync
hwsync
安腾: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 ish
dmb 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。