x86/x86_64 で順次整合性を確保するための 4 つの方法を次に示します。
- 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 実装
- Load Seq_Cst: MOV (メモリから)
- Store Seq Cst: (LOCK) XCHG // 代替: MOV (メモリへ),MFENCE
注: C/C++11 から x86 への代替マッピングがあり、Seq Cst ストアをロック (またはフェンシング) する代わりに、Seq Cst ロードをロック/フェンシングします。
- Load 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のLOAD(フェンスなし)およびSTORE+SFENCE?