問題タブ [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 - コンパイラ レベルおよびハードウェア レベルでのメモリ フェンシング
ここでメモリフェンシングについて読みました...そして、それについて少し説明が必要です
asm volatile ("" : : : "メモリ")
これにより、コンパイラ レベルのメモリ フェンスが提供され、プロセッサはこれを使用しても並べ替えを実行できます。
同様の命令でコンパイラレベルのフェンシングとプロセッサレベルのフェンシングの両方を達成できる方法はありますか?
私は遭遇しました、
asm volatile("sfence" : : : "メモリ")
これは何をしますか?コンパイラ レベルのストア フェンシングのみを提供しますか?
これに関する情報は非常に役立ちます。
ありがとう
java - jni/java: 事実上不変のネイティブ オブジェクトのスレッド セーフな公開/共有
1)いくつかのパラメーターを渡すネイティブJava関数があり、その実装はオブジェクトを作成するネイティブC ++コンストラクターであり、ポインターからオブジェクトにキャストされるlongを返します。このオブジェクトの構築されたメンバーは事実上不変です。C++ オブジェクトは、構築された状態に基づいて作業を行うことができます。
2) 関数呼び出しの結果を取得する Java コードは、ポインタの長いバージョンを (mutex なしで) どこかに安全に発行し、揮発性変数を変更して、ネイティブ C++ オブジェクトのメモリ変更を他のスレッドに発行することを期待しています。
ここで、別のスレッドが 2) の揮発性変数を読み取り、公開された long を取得し、C++ メモリ空間内の事実上不変オブジェクトにアクセスして何らかの作業を行う別のネイティブ関数を呼び出します。
質問: 揮発性とフェンスに関する Java メモリ モデルの保証により、他のスレッドは完全に構築されたネイティブ オブジェクトを参照することが保証されていますか? 一部のプラットフォームでは答えはイエスだと思いますが、フェンスを使用すると、さまざまなチップがさまざまな方法で機能することがわかり、Java が利用可能なすべてのプラットフォームについて疑問に思っていました。
java - オブジェクトが構築された後、他のスレッドとの間でメモリ フェンスが確立されますか?
コンストラクターの実行後に確立されたメモリ フェンスについての私の理解を誰かが検証してくれませんか。たとえば、Stock というクラスがあるとします。
さらに、コンストラクターが Thread1 によって実行され、Thread2によって(常に Thread2 によって)何度も呼び出されるとしますupdateQty()
。updatePrice()
私の主張は、Thread1 がオブジェクトを作成した後、オブジェクトの「可視性」が jvm 内の他のすべてのスレッドで確立されるということです。また、2 つの可変変数は Thread2 によってのみ変更されるため、ロックは必要ありません。私は正しいですか?
c++ - メモリバリア:初期化書き込みがワーカースレッドに確実に表示されるようにするにはどうすればよいですか?
私はメモリバリア/フェンスを使用したプログラミングにかなり慣れていません。セットアップの書き込みが、後で他のCPUで実行されるワーカー関数に表示されることをどのように保証できるのか疑問に思いました。たとえば、次のことを考慮してください。
その後(同時にではなく)、何度も何度も実行します。
CPU 2では、mySetup
が1の場合、 sheep
9であることが保証されますがmySetup
、0ではないことをどのように保証できますか?
これまでのところ、CPU 2で1になるまでスピンウェイトすることしか考えられません。しかし、スピンウェイトが最初に呼び出されたsetup
ときに待機するだけでよいことを考えると、これは非常に醜いようです。ManipulateSheep()
確かにもっと良い方法があるに違いありませんか?
初期化解除コードには対称的な問題もあることに注意してください。たとえば、存続期間中にメモリを割り当てるロックフリーのデータ構造を作成しているとします。デストラクタでは(すべてのスレッドがメソッドの呼び出しを終了したと仮定して)、すべてのメモリの割り当てを解除する必要があります。つまり、デストラクタを実行しているCPUが最新の変数値を持つ必要があります。デストラクタはそれをチェックするために「最新の」状態が何であるかを知る方法がないため、そのシナリオでスピン待機することさえできません。
編集:私が求めているのは、「すべてのストアが他のCPUに伝播するのを待つ」(初期化の場合)および「すべてのストアがCPUに伝播するのを待つ」(非初期化の場合)と言う方法はありますか?
c++ - 明示的なフェンスと std::atomic の使用の違いは何ですか?
アラインされたポインターのロードとストアがターゲット プラットフォーム上で自然にアトミックであると仮定すると、次の違いは何ですか。
これ:
この:
それらはすべて同等であるという印象を受けましたが、Relacyは最初のケース (のみ) でデータ競合を検出します。
Relacy の作成者に連絡して、これが予期された動作であるかどうかを確認しました。彼は、私のテストケースには確かにデータ競合があると言います。しかし、私はそれを見つけるのに苦労しています。誰かが私にレースが何であるかを指摘できますか? 最も重要なことは、これら 3 つのケースの違いは何ですか?
更新: Relacy は、スレッド間でアクセスされる変数のアトミック性(またはその欠如) について単に不平を言っている可能性があることに気づきました...結局のところ、このコードをプラットフォームでのみ使用するつもりであることを認識していません。ここで、整列された整数/ポインター アクセスは当然アトミックです。
別の更新: Jeff Preshing が、明示的なフェンスと組み込みのフェンス (「フェンス」と「操作」)の違いを説明する優れたブログ投稿を書きました。ケース 2 と 3 は明らかに同等ではありません。(とにかく、特定の微妙な状況では。)
assembly - この MMX メモリ コピー コードにはフェンスが必要ですか?
この基本的な mmx メモリ コピー コードは、リリース モードでメモリを破損しますが、これは特定のコンパイラでのみ発生します。特にVisual Studio 2010。このコードにはメモリ フェンスが必要なためだと思いますが、どこに行くのか、正確な理由はわかりません。このコードは、Visual Studio 2005 で完全に機能しました。
MMXMemCopy ENDP
c++ - QAtomicInt をメモリ フェンスとして使用する
再びロックフリーについて何か...
単純な配列ベースの整数の循環 FIFO を実装するとします。FIFO は、2 つのスレッドのシングル プロデューサー、シングル コンシューマーによってアクセスされます。読み取りインデックスと書き込みインデックスは、アイテムがアクセスされた後に常に更新されます。単一の CPU では、インデックスへの書き込みアクセス権を持つスレッドは 1 つだけなので、これは安全です (インデックスの更新操作がアトミックであると仮定します)。SMP マシンでは、キャッシュと再配列のために両方の CPU がインデックスの異なる表現を参照する可能性があるため、問題が発生する可能性があります。
QTには、メモリフェンスも実装するクロスプラットフォームのアトミック変数があります.QAtomicIntを使用すると、FIFO実装SMPが安全になりますか、それとも何かを見落としていますか?
c++ - アトミックデクリメントはインクリメントよりもコストがかかりますか?
Herb Sutter はブログで次のように書いています。
[...]スマート ポインター参照カウント のインクリメントは、通常、最適化された実装での通常のインクリメントと同じになるように最適化できる
shared_ptr
ためです。ただし、デクリメントはアトミック デクリメントまたは同等のものである必要があります。これは、それ自体がより高価な特別なプロセッサ メモリ命令を生成し、その上、周囲のコードの最適化にメモリ フェンスの制限を引き起こします。
テキストはの実装に関するものでshared_ptr
あり、彼の発言がこれにのみ当てはまるのか、それとも一般的に当てはまるのかはわかりません。彼の定式化から私が収集したのは、一般的に.
if(counter==0)
しかし、考えてみると、 が直後に続く場合の「より高価な減少」しか思い浮かびません。これはおそらく の場合shared_ptr
です。
したがって、アトミック操作++counter
は (通常)よりも常に高速なのか--counter
、それとも単に?if(--counter==0)...
shared_ptr
multithreading - C++11 メモリ フェンスを使用する場合
スレッド化された C++11 コードを書いていますが、メモリ フェンスなどをいつ使用する必要があるか完全にはわかりません。だからここに基本的に私がやっていることです:
別のスレッドで実行される Work() 関数で引数に安全にアクセスできるようにするには、どのような手順を実行する必要があるのか 疑問に思っていました。コンストラクターに記述して、別の関数でスレッドを作成するだけで十分ですか? または、メモリ フェンスが必要ですか? 3 つの引数すべてがメイン スレッドによって書き込まれ、ワーカー スレッドによって読み取られるようにメモリ フェンスを作成するにはどうすればよいですか?
助けてくれてありがとう!
multithreading - ミューテックス、アトミック、フェンス : 最高のトレードオフと移植性を提供するものは何ですか? C++11
C++ 11 でマルチスレッド アプリケーションを作成するときに、いくつのオプションがあるかをよりよく理解するために、さらに深く掘り下げようとしています。
要するに、これまでのところ、この 3 つのオプションが表示されます。
- 明示的なロックおよび解放メカニズムを備えたミューテックスは、ロックおよび解放によってスレッドの同期を維持します。これにはコストがかかり、コードの実行順序が保証されませんが、多くの場合、このソリューションは異なるメモリ モデル間で非常に移植性があります。
- アトミック操作。アトミック = 1 競合のない単一の操作であり、常に一貫性があるため、同期はロックと解放なしで達成されます。競合なしでロックする必要はありません。高度に最適化されたアトミック操作を使用しますが、アトミックは依然として私のコードが実行される順序。
- フェンスを使用すると、コード内にコンパイラが並べ替えできないブロックが作成され、柔軟性が低くなり、実際に何が実行されているかを常に監視する必要があるため、コードのメンテナンスの面でコストがかかる傾向があります。しかし、これらはキャッシング技術も改善します。この 3 つのソリューションの中で、おそらく最も予測可能な動作を持つソリューションです。
これは多かれ少なかれ、スレッドとメモリ モデルに関する最初のレッスンから得たものの核心です。私の問題は次のとおりです。
柔軟性と優れたパフォーマンスを実現するために、ロックフリーのデータ構造とアトミックを使用していました。ここでの問題は、明らかに X86 マシンが ARM マシンとは異なる方法でメモリの並べ替えを実行するという事実であり、コードの移植性を可能な限り維持したいと考えています。少なくともこの 2 つのプラットフォーム間では、2 つのプラットフォームが同じ並べ替えメカニズムを持つことが保証されていない場合、移植可能なマルチスレッド ソフトウェアを作成するためにどのようなアプローチを提案できますか? それとも、今のところアトミック操作が最良の選択であり、私はこれをすべて間違っていますか?
たとえば、Intel TBB ライブラリ (C++11 コードではない) が ARM/Android に移植され、atomic 専用の部分が大幅に変更されていることに気付きました。そのため、移植可能なマルチスレッド コードを C+ で記述できる可能性があります。 +11、ロックフリーのデータ構造を使用し、後でライブラリを別のプラットフォームに移植するときにアトミックに関する部分を最適化しますか?