問題タブ [memory-fences]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - C++ スレッド化と可視性の問題 - 一般的なエンジニアリングの実践とは?
私の研究から、飢餓、デッドロック、公平性、およびその他の並行性の問題の概念を知っています。ただし、理論は実践とはある程度異なります。また、実際のエンジニアリング タスクには、学術的なものよりも詳細な作業が含まれることがよくあります...
C++ 開発者として、私はスレッド化の問題についてしばらく心配していました...
x
プログラムのメモリの大部分を参照する共有変数があるとします。変数は 2 つのスレッドA
との間で共有されB
ます。
ここで、スレッドとスレッドのx
両方からの読み取り/書き込み操作を考えると、おそらく同時に、これらの操作を同期する必要がありますよね? したがって、へのアクセスには、たとえばミューテックスを使用して達成できる何らかの形式の同期が必要です。A
B
x
ここで、x
が最初に thread によって書き込まれ、次に(何らかの方法で)A
スレッドに渡され、そのスレッドが のみを読み取るという別のシナリオを考えてみましょう。次にスレッドは、 calledへの応答を生成し、それをスレッドに返します(これも何らかの形で)。私の質問は、このシナリオをスレッドセーフにするためにどの同期プリミティブを使用する必要があるかということです。アトミックと、さらに重要なメモリ フェンスについて読んだことがありますが、これらは信頼できるツールですか?B
x
B
x
y
A
これは、「クリティカル セクション」が存在する典型的なシナリオではありません。代わりに、一部のデータがスレッド間で渡され、同じメモリ位置に同時に書き込みが行われる可能性はありません。したがって、書き込まれた後、データは最初に何らかの形で「フラッシュ」され、他のスレッドが読み取り前に有効で一貫した状態でデータを確認できるようにする必要があります。文学ではどのように呼ばれていますか、それは「可視性」ですか?
とpthread_once
そのBoost/stdの対応物、つまりcall_once
. 「1回」機能によってアクセスされる一種の「メッセージキュー」を介してスレッド間でx
との両方が渡される場合、それは役立ちますか。y
私の知る限り、それは一種のメモリフェンスとして機能しますが、これについての確認は見つかりませんでした.
CPU キャッシュとその一貫性はどうですか? エンジニアリングの観点から、それについて何を知っておくべきですか? そのような知識は、上記のシナリオ、または C++ 開発で一般的に遭遇するその他のシナリオで役立ちますか?
多くのトピックを混在させている可能性があることは承知していますが、既知のパターンを再利用できるように、一般的なエンジニアリング プラクティスとは何かをよりよく理解したいと考えています。
この質問は、主に C++03 の状況に関連しています。これは私の日常の職場環境です。私のプロジェクトは主に Linux を使用するため、Boost.Atomic を含む pthread と Boost のみを使用できます。しかし、C++11 の登場により、そのような点に関して何か変化があったかどうかにも興味があります。
質問が抽象的であり、それほど正確ではないことは知っていますが、どんな入力も役立つ可能性があります。
concurrency - 取得フェンスと解放フェンスのこれらの定義は正しくありませんか?
Joe Duffy の並行プログラミングの本で、彼は取得フェンスと解放フェンスを次のように定義しています。
• フェンスを取得します。フェンスの後に来るロードまたはストアがフェンスの前に移動しないようにします。それ以前の指示は、フェンスの後にまだ移動する可能性があります。
• フェンスを解放します。フェンスの前に来るロードまたはストアがフェンスの後に移動しないようにします。それ以降の指示は、フェンスの前にまだ発生する可能性があります。
私の質問は次のとおりです。操作が何かの前に発生することは許可されていますが、後で発生することはできません。説明するのは難しいですが、これらのステートメントはどちらも鶏が先か卵が先かの問題のように思えます。
multithreading - Dekker 同期に C++11 acquire_release フェンスが十分でないのはなぜですか?
Dekker スタイルの同期の失敗は、通常、命令の並べ替えで説明されます。つまり、私たちが書くなら
次に、ロードをストアで並べ替えて、r1==r2==0
.
この種の並べ替えを防ぐために acquire_release フェンスを期待していました。
フェンスの上に荷物を移動できず、フェンスの下にストアを移動できないため、悪い結果を防ぐ必要があります。
ただし、実験によると、r1==r2==0
まだ発生する可能性があります。これについて並べ替えに基づく説明はありますか?私の推論のどこに欠陥がありますか?
multithreading - WC(Write Combined) としてマークされた PCIe を介してリモート メモリに書き込む場合、自動的に整合性が保たれますか?
x86 アーキテクチャでわかっているように、取得と解放の一貫性が自動的に提供されます。つまり、すべての操作はフェンスなしで自動的に順序付けられ、異なる場所からの最初の保存操作と次の読み込み操作は除外されます。(34ページでハーブ・サッターが言ったように: https://onedrive.live.com/view.aspx?resid=4E86B0CF20EF15AD!24884&app=WordPdf&authkey=!AMtj_EflYn2507c )
FSB を介してリモートのWC マーク付きメモリに書き込む場合、CPU はサイズが 64 バイトの一時バッファ (WCB (Write Combined Buffer)/BIU (Bus Interface Unit)) を使用します。また、「WCB が最終的に FSB を介して外部メモリにダンプされるとき、データは、以前のプログラムによるストアが実行された順序と同じ順序でメモリに書き込まれるとは限りません。」つまり、自動的に取得と解放の一貫性はありません-メモリを WC(Write Combined) としてマークした場合、一貫性は自動的に得られますか?からの引用 詳細については、1080 ページの「WCB FSB トランザクション」を参照してください。
しかし、リモートのWC マーク付きメモリに PCI Express 経由で書き込むとどうなるでしょうか? MOV または SSE を使用すると、自動的に取得と解放の一貫性が保たれるのでしょうか?
assembly - SFENCE + LFENCE が MFENCE と同等なのはなぜですか (または、そうでないのですか?)
プロセッサ x86/x86_64 で命令 LFENCE を行う意味はありますか?に対する以前の回答からわかるように、Sequential ConsistencySFENCE
の代わりに使用することはできません。MFENCE
MFENCE
そこの答えは、 = SFENCE
+ LFENCE
、つまり、LFENCE
それなしでは Sequential Consistency を提供できないことを示唆しています。
LFENCE
並べ替えを不可能にします:
-- へ -->
たとえば、メカニズムによって提供されるMOV [addr], reg
LFENCE
--> の並べ替え - Store Bufferは、パフォーマンス向上のために Store - Loads を並べ替えますが、それを妨げないためです。そして、このメカニズムを無効にします。LFENCE
MOV [addr], reg
LFENCE
SFENCE
LFENCE
並べ替えを不可能にするメカニズムは何ですか(x86 にはメカニズムがありません - Invalidate-Queue)?
また、SFENCE
MOV reg, [addr]
-->の並べ替えはMOV reg, [addr]
SFENCE
理論上のみ可能ですか、それとも実際には可能ですか? そして、可能であれば、実際には、どのようなメカニズムで、どのように機能するのでしょうか?
c++ - std::atomic::load のメモリ順序付け動作
アトミック::ロードがメモリバリアとしても機能し、以前のすべての非アトミック書き込みが他のスレッドから見えるようになると仮定するのは間違っていますか?
説明する:
スレッド 1:
スレッド 2:
両方の「トリガー」を実行した後、真になると予想しました。arm1 をアトミックにすることを提案しないでください。要点は、atomic::load の動作を調査することです。
私はメモリ順序のさまざまな緩和されたセマンティクスの正式な定義を完全には理解していないことを認めなければなりませんが、順次一貫性のある順序付けは、「すべてのスレッドがすべての変更を観察する単一の全体的な順序が存在する」ことを保証するという点で非常に簡単だと思いました同じ順番で。」これは、デフォルトのメモリ順序 std::memory_order_seq_cst を持つ std::atomic::load がメモリ フェンスとしても機能することを意味します。これは、「順次一貫性のある順序付け」の下にある次のステートメントによってさらに裏付けられます。
すべてのマルチコア システムで完全な順次順序付けを行うには、完全なメモリ フェンス CPU 命令が必要です。
しかし、以下の簡単な例は、MSVC 2013、gcc 4.9 (x86)、および clang 3.5.1 (x86) では、アトミック ロードが単純にロード命令に変換される場合に当てはまらないことを示しています。
gcc では次のようになります。
基本的に同じである msvc と clang は省略します。ARM の gcc では、期待どおりの結果が得られます。
これは学術的な質問ではありません。コード内で微妙な競合状態が発生し、std::atomic の動作に関する私の理解が疑問視されました。
java - C++ メモリ順序付けを Java にマッピングする
私は小さな C++ スニペットを Java に翻訳していますが、メモリの順序付け/フェンスについて 100% の自信はありません。これは正しいです:
C++:
Javaに翻訳する必要があると思う方法:
これは正しい線に沿っていますか?(そして、AtomicLong を使用するだけではなく、unsafe を使用する理由もあります)
objective-c - dispatch_async() などはメモリ フェンスを提供しますか?
などを介して任意のキューでブロックを実行するdispatch_async
と、GCD はブロック呼び出しの周りにスレッド フェンスを提供しますか? そうだと思いますが、ドキュメントには、私が知る限り、何らかのヒントはありません。