問題タブ [memory-barriers]
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++ - ロック保護されたデータのキャッシュ一貫性
以下の f() でスレッド TA と TB が競合している場合:
TB は、ロックを取得したときに、キャッシュされた 'a' のコピーが古くなっていることをどのように知るのでしょうか?
これは、アトミックやメモリ バリアを明示的に使用せずに人々が何年にもわたってプログラミングしてきた方法であり、すべて正常に動作します。ミューテックス (またはスピンロック) を取得すると、暗黙的なメモリ バリアが発行されますか? ありがとう。
編集: たぶんこれは、ミューテックスロック機能は揮発性なしで十分ですか?の複製です。.
linux - Linux カーネルのメモリ バリア
Linuxカーネルプログラミングは初めてです。GUARANTEESの章にあるメモリバリアのドキュメントに混乱しています。
特定の CPU 内でオーバーラップするロードとストアは、その CPU 内で順序付けされているように見えます。
CPU は以下のみを発行します。
そして、その後の別の例:
オーバーラップするメモリアクセスはマージまたは破棄される可能性があると想定する必要があります。
次のいずれかを取得できます。
これらは同じように見えますが、2 つの例の違いは何ですか?
linux - Linuxカーネル循環バッファについて
Linuxカーネルの循環バッファの実装について説明している記事がhttp://lwn.net/Articles/378262/にあります。いくつか質問があります:
これが「プロデューサー」です。
質問:
- このコードはメモリオーダリングとアトミック性を明示的に扱っているので、spin_lock()のポイントは何ですか?
- これまでのところ、ACCESS_ONCEはコンパイラの並べ替えを停止するというのが私の理解ですが、本当ですか?
- produce_item(item)は、アイテムに関連付けられたすべての書き込みを発行するだけですか?
- smp_wmb()は、それに続く「公開」書き込みの前に、produce_item(item)へのすべての書き込みが完了することを保証すると思います。本当ですか?
- このコードを入手したページの解説は、ヘッドインデックスを更新した後、通常はsmp_wmb()が必要になることを示唆しているようですが、wake_up(consumer)はこれを行うため、必要ありません。本当?もしそうなら、なぜですか?
これが「消費者」です。
「消費者」に固有の質問:
- smp_read_barrier_depends()は何をしますか?フォーラムのいくつかのコメントから、ここでsmp_rmb()を発行できたようですが、一部のアーキテクチャでは、これは不要(x86)で高すぎるため、オプションでこれを行うためにsmp_read_barrier_depends()が作成されました...なぜsmp_rmb()が必要なのか本当に理解できません!
- smp_mb()は、それ以前のすべての読み取りが、その後の書き込みの前に完了することを保証するためにありますか?
memory-barriers - JMMクックブックの混乱のメモリバリアの例
私は、JMM クックブック http://g.oswego.edu/dl/jmm/cookbook.htmlでのバリアの例のこのコンパイラ挿入と混同しています。
i = u (u からの揮発性ロードと、通常の i へのストアを伴いませんか?)
j = b (私には b からの通常のロードと j への通常のストアが見えます)
クックブックのルックアップ テーブルによると、LoadLoad と LoadStore の 2 つのバリアはどこから来るのでしょうか?
ありがとう!
///////////////// JSRの例 ////
揮発性 int u;
int i、b、j;
私は= u; //あなたをロード
j = b; //ロードb
c++ - このメモリバリアは正しく実装されていますか?
以下のようにメモリ バリアが定義されている従来の C++ コードを読んでいます。主な OS は linux と vxworks です。コンパイラは gcc (WindRiver の gcc) です。
しかし、ノーオペレーション操作がどのように機能してメモリバリアを生成するのかわかりませんか? または、それは単なる障害の実装ですか?
java - プリミティブ配列書き込みの Java 同時可視性
最近、コードベースでこの宝石を見つけました:
これは次のように使用されます。
スレッド 1
スレッド 2
スレッド 1 は、継続的に実行されるバックグラウンド更新スレッドです。スレッド 2 は HTTP ワーカー スレッドであり、読み取った内容が何らかの形で一貫性があるか原子的であるかを気にせず、書き込みが「最終的に」そこに到達し、並行性の神への供物として失われないことだけを気にします。
さて、これは私のすべての警告ベルをトリガーします。無関係なコードの奥深くに記述されたカスタム同時実行アルゴリズム。
残念ながら、コードの修正は簡単ではありません。同時プリミティブ行列に対する Java サポートは適切ではありません。これを修正する最も明確な方法は を使用するように見えますがReadWriteLock
、それはおそらくパフォーマンスに悪影響を及ぼすでしょう。正確さは明らかにより重要ですが、パフォーマンスに敏感な領域からそれを切り取る前に、これが正しくないことを証明する必要があるようです.
java.util.concurrent のドキュメントによると、次のようにhappens-before
関係が作成されます。
スレッド内の各アクションは、プログラムの順序で後で来るそのスレッド内のすべてのアクションの前に発生します。
揮発性フィールドへの書き込みは、同じフィールドの後続のすべての読み取りの前に発生します。volatile フィールドの書き込みと読み取りには、モニターの開始と終了と同様のメモリ整合性効果がありますが、相互排他ロックは必要ありません。
したがって、次のように聞こえます。
- マトリックス書き込みは公開前に発生します() (ルール 1)
- publish() は syncChanges() の前に発生 (ルール 2)
- syncChanges() マトリックス読み取りの前に発生 (ルール 1)
したがって、コードは実際にマトリックスの事前発生チェーンを確立しています。
しかし、私は確信していません。並行性は難しく、私はドメインの専門家ではありません。私は何を逃したのですか?これは本当に安全ですか?
c - mutex_unlockはメモリフェンスとして機能しますか?
ここで説明する状況は、iPad 4(ARMv7s)で発生しており、posixlibsを使用してロック/ロック解除をミューテックスします。ただし、他のARMv7デバイスでも同様のことが見られます(以下を参照)。したがって、どのソリューションでも、ARMv7のミューテックスとメモリフェンスの動作をより一般的に調べる必要があると思います。
シナリオの擬似コード:
スレッド1–データの生成:
スレッド2–データの消費:
以前(iPad 2で問題が発生したとき)、私はmSharedProducerIndex = TempProducerIndex
それがアトミックに実行されていないと信じていたので、AtomicCompareAndSwap
を割り当てるためにを使用するように変更しましたmSharedProducerIndex
。これはこの時点まではうまくいきましたが、私が間違っていたことが判明し、バグが戻ってきました。「修正」はタイミングを変えただけだと思います。
私は今、実際の問題はミューテックスロック内での書き込みのアウトオブオーダー実行であるという結論に達しました。つまり、コンパイラまたはハードウェアのいずれかが並べ替えを決定した場合です。
... に:
...そして、コンシューマーがプロデューサーをインターリーブした場合、コンシューマーがデータを読み取ろうとしたときに、データはまだ書き込まれていませんでした。
したがって、メモリバリアについて読んだ後、信号を外部の消費者に移動してみようと思いましmutex_unlock
た。ロックを解除すると、次の場所に確実mSharedArray
に書き込まれるメモリバリア/フェンスが生成されると信じていました。
mutex_unlock
しかし、これはまだ失敗し、aが確実に書き込みフェンスとして機能するかどうか疑問に思いますか?
また、コンパイラがコードをsに移動できる(ただし、sから移動できない)ことを示唆するHPの記事も読みましたcrit_sec
。したがって、上記の変更後でも、書き込みはmSharedProducerIndex
バリアの前にある可能性があります。この理論にマイレージはありますか?
明示的なフェンスを追加することで、問題は解消されます。
したがって、私は問題を理解しており、フェンスが必要であると思いますが、ロック解除の動作と、それがバリアを実行していないように見える理由についての洞察は非常に役立ちます。
編集:
コンシューマースレッドにミューテックスがないことについて:私はint mSharedProducerIndex
単一の命令であるという書き込みに依存しているため、コンシューマーが新しい値または古い値のいずれかを読み取ることを望んでいます。どちらも有効な状態であり、それmSharedArray
が順番に(つまり、書き込む前にmSharedProducerIndex
)書き込まれる場合、これは問題ありませんが、これまでの説明から、これについては返信できません。
mSharedProducerIndex
同じロジックにより、書き込みがバリア内に移動する可能性があり、したがって誤って並べ替えられる可能性があるため、現在のバリアソリューションにも欠陥があるように見えます。
読み取りバリアとして機能するために、コンシューマーにミューテックスを追加することをお勧めしますか、それともPPCpragma
のように、プロデューサーでアウトオブオーダー実行を無効にするための命令がありますか?EIEIO
c++ - x86 ライクなシステムでは、C++11 メモリ バリアはどのように実装されていますか?
私は C++11 のstd::memory_order
型 (リラックス、取得リリース、逐次一貫性など) の概念を十分に理解していますが、x86 で (コンパイラによって) 通常どのように実装されているかをよりよく理解したいと思っています (または x86_64) ターゲット。
memory_order_consume
具体的には、各順序制約 ( 、memory_order_acquire
、memory_order_release
、および)の低レベルの詳細 (プロセッサ間の状態またはキャッシュを同期するための重要なメモリ関連の CPU 命令など) の比較memory_order_seq_cst
。
できればx86_64または同様のアーキテクチャについて、できるだけ低レベルの詳細を提供してください。あなたの助けは非常に高く評価されます。