私は Herb の素晴らしい「原子兵器」の講演を 2 回目で探しており、全記憶モデル / 逐次的一貫性の物語を経る概念に頭を悩ませようとしています。概念レベルで気になることが 1 つあります。この話から得た教訓の 1 つは、atomics を使用することで、他の方法ではコンパイラーが検出できないスレッド間の相互作用について、コンパイラーに「ヒント」を与えることができるということです。
そこで、次のシナリオについて心配し始めました。
int local_copy_of_shared_var = shared_var;
if (local_copy_of_shared_var > some_threshold)
{
DoSomething();
}
... Do some work
if (local_copy_of_shared_var > some_threshold)
{
DoSomethingElse();
}
この場合、Hans Bohem が「「無害な」データ競合を含むプログラムを誤ってコンパイルする方法」で指摘したように (変数名は上記のスニペットに合わせて調整されています):
2 つのテストの間に local_copy_of_shared_var を含むレジスタをスピルする必要があるとコンパイラが判断した場合、値の格納を回避し (結局のところ、これは単に shared_var のコピーにすぎません)、代わりに単純に shared_var の値を再読み取りすることを決定する可能性があります。 local_copy_of_shared_var を含む 2 番目の比較。
[...] 核となる問題は、変数値は明示的な代入なしでは非同期に変更できないという仮定をコンパイラが利用することから生じます。私たちの設定のようにデータ競合が言語仕様で許可されていない場合、そのような仮定は完全に正当です。データ競合がなければ、このような非同期変更は不可能です
ここで、アトミック (デフォルトの seq_cst メモリー順序付け) はデータ競合がないことを保証する必要があり、それらは異なるスレッド間でそのような変数に相互作用があるというコンパイラーへの「ヒント」であるため、前述のアトミックを使用すると主張することができますスニペットは、コンパイラがshared_varからそのような「再読み取り」を挿入するのを防ぎ、代わりにlocal_copy_of_shared_varを「ワンショット」スナップショットと見なして、2 つのテスト間の矛盾を回避しますか?
常識に基づいて、ここでアトミックを使用するだけで、2 つのテスト間でlocal_copy_of_shared_varが更新されないようにコンパイラが対策を講じることが保証されるとは思わないため、私の推論には何か問題があると思います。一方、Herb が講演で述べているように、メモリ モデルは、アトミックを使用する場合にコンパイラによって偽のメモリ操作が追加されないことを保証するようになりました。 "安全"。私は非常に混乱しており、コミュニティからの意見を聞きたいと思っています。私の推論にバグがある場合は、おそらく修正してもらいたいと思っています。