2013-09-02 19 views
7

キャッシュやパイプラインのためのプロセッサ命令を必要としないmemory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel操作load()store()メモリバリアのためのx86、およびアセンブラのコードに常にstd::memory_order_relaxedに対応し、これらの制限は、唯一の最適化のために必要であることが知られていますコンパイラ:http://www.stdthread.co.uk/forum/index.php?topic=72.0`std :: memory_order_acquire`のセマンティクスにはx86/x86_64のプロセッサ命令が必要ですか?

そして、このコードの逆アセンブルコードがstore()(MSVS2012 x86_64版)のためにこれを確認:

std::atomic<int> a; 
    a.store(0, std::memory_order_relaxed); 
000000013F931A0D mov   dword ptr [a],0 
    a.store(1, std::memory_order_release); 
000000013F931A15 mov   dword ptr [a],1 

しかし、使用してload()MSVS2012 x86_64版)のためにこれをしないかご確認くださいこのコード、lock cmpxchg

int val = a.load(std::memory_order_acquire); 
000000013F931A1D prefetchw [a] 
000000013F931A22 mov   eax,dword ptr [a] 
000000013F931A26 mov   edx,eax 
000000013F931A28 lock cmpxchg dword ptr [a],edx 
000000013F931A2E jne   main+36h (013F931A26h) 

    std::cout << val << "\n"; 

しかしAnthony Williams said

some_atomic.load(STD :: memory_order_acquireは)ちょうどん 単純なロード命令と some_atomic.store(std :: memory_order_release)が単純なに分岐しますストア命令。

どこが間違っている、とアンソニー・ウィリアムズが言ったようにstd::memory_order_acquireのセマンティクスは、x86/x86_64のlock cmpxchgまたは単純なロード命令mov上のプロセッサ命令を必要としていますか?

ANSWER:それは、このバグレポートと同じです:http://connect.microsoft.com/VisualStudio/feedback/details/770885

+1

コンパイラが生成するものを見ても、特定の機能の要件を判断するためには必ずしも良い方法ではないかと思っています。コンパイラが「必要以上に」行っていることはあまりありません。 –

+0

@Mats Peterssonはい、何もしないよりも簡単なことはありません。そして、それはコンパイラから必要とされたもので、 'mov'だけでした。実際、マイクロソフトの開発者はこれを最も単純なタスク、「何もしない」で失敗しましたか? :) – Alex

+0

私はMSのVC(少なくともいくつかのバージョン)は、 "volatile"と宣言された変数に余分な "ロック"を生成することを知っています - C++の標準では必要ではなく、 SMPシステムを使用するとうまく動作しません。これらの状況の1つに似ています。 –

答えて

6

std::memory_order_acquireのセマンティクスは、x86/x86_64の上のプロセッサ命令を必要としません。

x86_64でのload()/ store()操作では、プロセッサ命令(ロック/フェンス)の正確度はatomic.store(val, std::memory_order_seq_cst);であり、それにはまたは代替:MOV (into memory),MFENCEが必要です。

プロセッサ(CAS除く)x86用のメモリの障壁命令し、またARMおよびPowerPC:http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html

逆アセンブラGCC 4.8.1 x86_64版 - GDB - 負荷()

20  temp = a.load(std::memory_order_relaxed); 
    21  temp = a.load(std::memory_order_acquire); 
    22  temp = a.load(std::memory_order_seq_cst); 
0x46140b <+0x007b>   mov 0x38(%rsp),%ebx 
0x46140f <+0x007f>   mov 0x34(%rsp),%esi 
0x461413 <+0x0083>   mov 0x30(%rsp),%edx 

ディスアセンブラGCC 4.8。1つのx86_64版 - GDB - ストア()

a.store(temp, std::memory_order_relaxed); 
a.store(temp, std::memory_order_release); 
a.store(temp, std::memory_order_seq_cst); 
0x4613dc <+0x004c>   mov %eax,0x20(%rsp) 
0x4613e0 <+0x0050>   mov 0x38(%rsp),%eax 
0x4613e4 <+0x0054>   mov %eax,0x20(%rsp) 
0x4613e8 <+0x0058>   mov 0x38(%rsp),%eax 
0x4613ec <+0x005c>   mov %eax,0x20(%rsp) 
0x4613f0 <+0x0060>   mfence 
0x4613f3 <+0x0063>   mov %ebx,0x20(%rsp) 

逆アセンブラMSVS 2012 x86_64版 - ロード() - それは、このバグ報告と同じである:http://connect.microsoft.com/VisualStudio/feedback/details/770885

temp = a.load(std::memory_order_relaxed); 
000000013FE51A1F prefetchw [a] 
000000013FE51A24 mov   eax,dword ptr [a] 
000000013FE51A28 nop   dword ptr [rax+rax] 
000000013FE51A30 mov   ecx,eax 
000000013FE51A32 lock cmpxchg dword ptr [a],ecx 
000000013FE51A38 jne   main+40h (013FE51A30h) 
000000013FE51A3A mov   dword ptr [temp],eax 
    temp = a.load(std::memory_order_acquire); 
000000013FE51A3E prefetchw [a] 
000000013FE51A43 mov   eax,dword ptr [a] 
000000013FE51A47 nop   word ptr [rax+rax] 
000000013FE51A50 mov   ecx,eax 
000000013FE51A52 lock cmpxchg dword ptr [a],ecx 
000000013FE51A58 jne   main+60h (013FE51A50h) 
000000013FE51A5A mov   dword ptr [temp],eax 
    temp = a.load(std::memory_order_seq_cst); 
000000013FE51A5E prefetchw [a] 
    temp = a.load(std::memory_order_seq_cst); 
000000013FE51A63 mov   eax,dword ptr [a] 
000000013FE51A67 nop   word ptr [rax+rax] 
000000013FE51A70 mov   ecx,eax 
000000013FE51A72 lock cmpxchg dword ptr [a],ecx 
000000013FE51A78 jne   main+80h (013FE51A70h) 
000000013FE51A7A mov   dword ptr [temp],eax 

逆アセンブラMSVS 2012 x86_64 - store()

a.store(temp, std::memory_order_relaxed); 
000000013F8C1A58 mov   eax,dword ptr [temp] 
000000013F8C1A5C mov   dword ptr [a],eax 

    a.store(temp, std::memory_order_release); 
000000013F8C1A60 mov   eax,dword ptr [temp] 
000000013F8C1A64 mov   dword ptr [a],eax 

    a.store(temp, std::memory_order_seq_cst); 
000000013F8C1A68 mov   eax,dword ptr [temp] 
000000013F8C1A6C xchg  eax,dword ptr [a] 
関連する問題