2016-07-21 3 views
0

私がコンパイルされ、アセンブリのための出力に分析しました:私はそれが実際にatomic storeを実装されているんどのように見てみたいアトミックストア。構造

struct S{ 
public: 
    int a,b,c,d,e,f,g,h,i,j,k; 
}; 

int main() { 
    S s; 
    std::atomic<S> as; 
    as.store(s); 
    return 0; 
} 

を。 "小さな"オペランドを整列するのは簡単です。しかし、今や我々はより広いオペランドを持っているので、より複雑な状況です。私の他の質問(Atomicity on x86)@Peterコルドで

は言った:広いオペランドについては

を、アトミック構造体の複数の エントリに新しいデータを書き込むように、あなたはすべての ロックでそれを保護する必要がありますそれを尊重します。

OK(あなたは。ロックせずにそれをエミュレートする方法 がないことに注意してください。アトミック16bのストアを行うために再試行ループで cmpxchg16b x86のロックを使用することができる場合があります)が、それは正確に何を意味するのでしょ?ロックするのはどういう意味ですか? 特に、私はlockが "接頭語"命令のアトミック性を保証するプレフィックスであることを知っています。特に、@Peterコルドは言った:

をあなたが、私はそれをアトミックを維持することができる方法を理解することはできませんアトミック16bのストア

を行うために再試行ループでのx86ロックcmpxchg16b を使用することができる可能性が?確かに、16Bのメモリチャンクは原子的に格納できると思いますか?しかし、次の反復についてはどうですか?

私はそれを表現するのに問題があったので私の疑いが理解できることを願っています。


私は、上記のプログラムをデバッグしてそして、私の目には、魔法はatomic_storeの背後にあります。 この関数は@Peter Cordesが言ったことを実行すると思います。誰かが望むなら、私はここに貼り付けることができ__atomic_store

+4

あなたは生成されたマシンコードを分析したと言いました。さて、あなたは*これがどのように実装されているかを私たちに伝えることができます! –

+0

はい、__atomic_storeの逆アセンブリで貼り付けてください。 gccは、格納されるデータを参照渡しで呼び出します。 –

+0

ここに質問がありませんか? –

答えて

3

を解体あなたは

原子16Bストアを行うために再試行ループでのx86ロックcmpxchg16bを使用することができるかもしれ私は本当に代わり16Bの16bと言っていましたか?おっとっと。より大きな編集の一部としてそれを修正します。

1つを 16Bアトミックストアにすることはできますが、比較部分が成功するまで再試行を続ける読み取り - 変更 - 書き換えとして実行します。これを使って16B以上をアトミックに格納することはできません。


それがロックする何を意味するのでしょうか?特に、ロックは「接頭辞」命令のアトミック性を保証する接頭辞であることを知っています。

接頭辞はlockではなく、スピンロック/ミューテックスのようにロックします。 lockという接頭辞は、読み取り - 改変 - 書き込み命令でのみ機能します。アライメントのとれていないアトミックなアトムを行うにはlock mov [mem], eaxはありません。 lock edバスサイクルは常に、リードモディファイライトです。cmpxchgのドキュメントでインテルが文書化しています。したがって、lock movストアは、メモリーマップI/Oで使用する場合、セマンティクスが異なるロードも生成します。 (読み取りは副作用を引き起こす可能性があります)。


私はなぜあなたはmain()でそのコードを入れて、assから初期化されていないごみを格納しますコンパイルと...

ためのアセンブリ出力を解析してきましたか?それ以外にも、mainはいくつかの点で特別です。 argをとる(またはグローバルに影響を与える)関数を書く方が良いでしょう。 atomic<s>は、gccが本当に何をしているのかを確かめたいなら、部分的に最適化される可能性のあるローカルではなく、グローバルである必要があります。

#include <atomic> 
struct S{ int a,b,c,d,e,f,g,h,i,j,k; }; // or int a[11] 
std::atomic<S> as; 
void atomic_struct_store_zero() { 
    S s = { 0 };  // initializes all members to zero 
    as.store(s); 
} 

srcとdestのポインタとサイズを渡す__atomic_storeこのcompiles to関数呼び出しは、。おそらくそれはどこかでロックを使用しますが、ロックはasの一部ではありません。 (sizeof(as) == sizeof(S) == 44)。