web-dev-qa-db-ja.com

c ++、std :: atomic、std :: memory_orderとは何ですか?

誰でもstd::memory_orderをわかりやすい英語で説明し、std::atomic<>でどのように使用するか説明できますか?

ここで参考文献といくつかの例を見つけましたが、まったく理解できません。 http://en.cppreference.com/w/cpp/atomic/memory_order

69
2607

誰でもstd :: memory_orderが何であるかを分かりやすい英語で説明できますか、

さまざまなメモリの順序付けで私が見つけた最もわかりやすい「平易な英語」の説明は、リラックスしたアトミックに関するBartoz Milewskiの記事です。 http://bartoszmilewski.com/2008/12/01/c-atomics-and-memory-注文/

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

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

そして、それらをstd :: atomic <>でどのように使用しますか?

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

上記の2番目の記事で、Bartoz Milewskiは次の結論に達しています。

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

22
je4d

std::memory_order値を使用すると、アトミック操作によって提供されるメモリの順序付けにきめ細かな制約を指定できます。複数のスレッドからアトミック変数を変更してアクセスする場合、std::memory_order値を操作に渡すと、relaxこれらのアトミック変数に対する操作が他のスレッドから見えるようになる順序と、それらの操作がアプリケーション内の非アトミックデータに及ぼす同期効果に関するコンパイラーとプロセッサー。

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++メモリモデル、アトミック操作とstd::memory_order制約の詳細、およびさらなる章(44ページ)の章全体(45ページ)を取り上げていますロックフリーのデータ構造での同期のためのアトミック操作の使用、および緩和された順序付け制約の結果。

相互排除のための Dekker's algorithm および Peterson's algorithm に関する私のブログエントリは、いくつかの問題を示しています。

35

いいえ。「わかりやすい英語」の説明は32ページあり、 ここ で見つけることができます。

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

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

15
zvrba

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

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

並べ替え自体についても、 CPU Reordering -と考えることもできます。コンパイラも並べ替えを行っている可能性があります。

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

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

5

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

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

4
plan9assembler