以下是在 x86/x86_64 中实现顺序一致性的四种方法:
- LOAD(无围栏)和 STORE+MFENCE
- LOAD(无围栏)和LOCK XCHG
- MFENCE+LOAD 和 STORE(不带围栏)
- LOCK XADD(0) 和 STORE(无栅栏)
正如这里所写:http: //www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
C/C++11 操作 x86 实现
- 加载 Seq_Cst:MOV(从内存中)
- Store Seq Cst: (LOCK) XCHG // 替代: MOV (入内存),MFENCE
注意:有一个 C/C++11 到 x86 的替代映射,而不是锁定(或隔离) Seq Cst 存储锁定/隔离 Seq Cst 负载:
- 加载 Seq_Cst: LOCK XADD(0) // 备选方案:MFENCE,MOV(从内存中)
- Store Seq Cst: MOV (入内存)
GCC 4.8.2(x86_64 中的 GDB )对C++11-std::memory_order_seq_cst使用 first(1) 方法,即 LOAD(无围栏)和 STORE+MFENCE:
std::atomic<int> a;
int temp = 0;
a.store(temp, std::memory_order_seq_cst);
0x4613e8 <+0x0058> mov 0x38(%rsp),%eax
0x4613ec <+0x005c> mov %eax,0x20(%rsp)
0x4613f0 <+0x0060> mfence
众所周知,MFENCE = LFENCE+SFENCE。然后这段代码我们可以重写为:LOAD(without fence) and STORE+LFENCE+SFENCE
问题:
- 为什么我们这里不需要在 LOAD 之前使用 LFENCE,而需要在 STORE 之后使用 LFENCE(因为 LFENCE 只有在 LOAD 之前才有意义!)?
- 为什么 GCC 不使用方法:对于 std::memory_order_seq_cst 的加载(无围栏)和 STORE+SFENCE?