83

誰もstd::memory_orderが平易な英語で何があり、それらをどのように使用するかを説明できますstd::atomic<>か?

ここでリファレンスといくつかの例を見つけましたが、まったく理解していません。 http://en.cppreference.com/w/cpp/atomic/memory_order

4

5 に答える 5

51

これらのstd::memory_order値を使用すると、アトミック操作によって提供されるメモリ順序にきめ細かい制約を指定できます。複数のスレッドからアトミック変数を変更してアクセスする場合はstd::memory_order、操作に値を渡すことで、これらのアトミック変数の操作が他のスレッドに表示される順序と同期に関するコンパイラーとプロセッサーの制約を緩和できます。これらの操作がアプリケーションの非アトミックデータに与える影響。

のデフォルトの順序std::memory_order_seq_cstは最も制約があり、予想される「直感的な」プロパティを提供します。スレッドAがデータを格納し、を使用してアトミックフラグを設定すると、std::memory_order_seq_cstスレッドBはフラグが設定されていることを確認すると、書き込まれたデータを確認できます。スレッドAによる。他のメモリ順序値は必ずしもこの保証を提供するわけではないため、非常に注意深く使用する必要があります。

基本的な前提は次のとおりです。(a)自分が何をしているかを本当に理解していて、リラックスした使用法がすべての場合に安全であることを証明std::memory_order_seq_cstできる場合を除き、(デフォルト)以外のものを使用しないでください。(b)プロファイラーがリラックスした順序で使用する予定のデータ構造と操作がボトルネックになっています。

私の本「C++Concurrency in Action」では、C ++メモリモデル、アトミック操作と制約の詳細について全章(45ページ)を取り上げstd::memory_order、ロックフリーデータ構造での同期にアトミック操作を使用することについてさらに1章(44ページ)を取り上げています。 、および緩和された順序制約の結果。

デッカーのアルゴリズムピーターソンの相互排除アルゴリズムに関する私のブログエントリは、いくつかの問題を示しています。

于 2012-03-05T10:11:52.407 に答える
28

誰でもstd::memory_orderを平易な英語で説明できますか?

さまざまなメモリオーダリングについて私が見つけた最高の「プレーンイングリッシュ」の説明は、リラックスしたアトミックに関するBartoz Milewskiの記事です:http://bartoszmilewski.com/2008/12/01/c-atomics-and-memory-ordering/

そしてフォローアップの投稿: http: //bartoszmilewski.com/2008/12/23/the-inscrutable-c-memory-model/

ただし、これらの記事は優れた入門書ですが、C ++ 11標準よりも前のものであり、安全に使用するために知っておく必要のあるすべてのことを説明しているわけではないことに注意してください。

そしてそれらをstd::atomic <>で使用する方法は?

ここでのあなたへの私の最善のアドバイスは:しないでください。リラックスしたアトミックは、(おそらく)C++11で最もトリッキーで最も危険なものです。リラックスstd::atomic<T>したメモリオーダリングを使用することで解決できるパフォーマンスの問題があることを本当に確信できるまで、デフォルトのメモリオーダリング(逐次一貫性)を維持します。

上記のリンク先の2番目の記事で、BartozMilewskiは次の結論に達しました。

C ++の弱いアトミックについて推論しようとしたときに、自分が何に夢中になっているのかわかりませんでした。それらの背後にある理論は非常に複雑であるため、境界線は使用できません。比較的単純なアルゴリズムの証明を完了するには、3人(Anthony、Hans、および私)と標準の変更が必要でした。弱いアトミックに基づくロックフリーキューに対して同じことを行うことを想像してみてください!

于 2012-03-05T03:38:41.550 に答える
18

いいえ。「平易な英語」の説明は32ページで、ここにあります

それを読みたくない場合は、リンク先のページに、デフォルトは「常に正しいことを行う」設定である逐次一貫性のある順序であると記載されているため、メモリの順序付けを忘れることができます。

他の設定を使用するには、上記の論文とその中の例を実際に読んで理解する必要があります。

于 2012-03-04T09:10:39.667 に答える
5

簡単に言うと、コンパイラとCPUは、記述した方法とは異なる順序で命令を実行する場合があります。シングルスレッドの場合、これは正しく表示されるため、問題にはなりません。複数のプロセッサ上の複数のスレッドの場合、これが問題になります。C ++でのメモリの順序付けは、コンパイラ/ CPUが実行できることを制限し、そのような問題を修正します。

たとえば、ダブルチェックロックに関する私の記事を見ると、そのパターンで順序付けがどのように混乱しているかがわかります。これは、アトミックメモリの順序付けを使用して修正できることを示しています。

並べ替え自体については、CPUの並べ替えも検討できます。繰り返しになりますが、コンパイラも並べ替えを行っている可能性があります。

このトピックに関するドキュメント(私のものを含む)は、理論的なシナリオについて説明していることに注意してください。x86などの最も一般的なCPUには、非常に強力な順序付け保証があり、多くの明示的な順序付けは必要ありません。したがって、適切なC ++ 11アトミックを使用しなくても、コードは機能する可能性があります。

zvrbaが述べたように、トピックは実際には非常に詳細です。メモリバリアに関するLinuxカーネルのドキュメントにも多くの詳細情報が含まれています。

于 2012-03-04T11:37:49.987 に答える
3

GCCwikiにはいくつかのわかりやすい英語があります。;)

http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync

于 2012-03-12T14:26:15.827 に答える