問題タブ [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++ - ユーザー空間のメモリバリア? (Linux、x86-64)
カーネル側でメモリ バリアを設定するのは簡単です。マクロ mb、wmb、rmb などは、Linux カーネル ヘッダーのおかげで常に配置されています。
ユーザー側でこれを達成する方法は?
c# - メモリバリアと大きな構造体?
100 バイトで構成される構造体があるとします。次のコードについてどのような保証がありますか?
メモリ モデルは、メモリ バリアの配置後に 100 バイトのコピーが完了することを保証しますか? またはメモリバリアは、プロセッサのアーキテクチャのサイズの型にのみ適用されますか? (32bit の場合は 4 バイト、64bit の場合は 8 バイト)。これがvolatileキーワードがプリミティブ型にのみ適用される
理由ですか? (8 バイトのメンバーを volatile として宣言すると、インターロックされた命令を使用してその値を変更することになりますか?[32 ビット マシンでは 4 バイトを超える型の原子性は保証されないため])。
私は十分に明確だったと思います.. :)
ありがとう
multithreading - 読み取りメモリバリアと揮発性を理解するにはどうすればよいですか
一部の言語はvolatile
、変数をバックアップするメモリを読み取る前に「メモリバリアの読み取り」を実行すると説明される修飾子を提供します。
読み取りメモリバリアは、一般に、CPUがバリアの後に要求された読み取りを実行する前に、バリアの前に要求された読み取りを実行したことを確認する方法として説明されます。ただし、この定義を使用すると、古い値を読み取ることができるように見えます。つまり、特定の順序で読み取りを実行することは、メインメモリまたは他のCPUを調べて、読み取りバリア時のシステムの最新値を実際に反映したり、その後に書き込みを行ったりする必要があることを意味するわけではありません。読み取りバリア。
それで、volatileは、最新の値が読み取られることを本当に保証しますか、それとも、読み取られる値が少なくともバリア前の読み取りと同じくらい最新であることを保証しますか?または他の解釈?この答えの実際的な意味は何ですか?
.net - .NET で lock と MemoryBarrier をいつ使用するか
.NET では、キーワードはandをlock
囲む構文糖衣であるため、このコードは次のように言えます。Monitor.Enter
Monitor.Exit
と同じです
ただし、.NET フレームワークにはMemoryBarrier
、同様の方法で機能するクラスも含まれています。
/バージョンでいつ使用Thread.MemoryBarrier
したいのか混乱していますか? 私は、それらが同じように機能すると述べている Threading Tutorialによってさらに混乱しています。lock
Monitor
私が見る限り、目に見える違いはロックオブジェクトを必要としないことです。これを使用すると、単一のスレッド上にあるMonitor
スレッド間で何かを行うことができると思います。MemoryBarrier
私の直感によると、もう 1 つの重要な違いはMemoryBarrier
変数のみであり、メソッドではありません。
最後に、これは既存の質問「いつスレッドセーフ ロック コードで 'volatile' または 'Thread.MemoryBarrier()' を使用するか?」とは関係ありません。(C#)volatile
、それは私がその使用法を理解しているキーワードに焦点を当てているためです。
c++ - _ReadWriteBarrier はどのようにコール ツリーを伝播しますか?
Visual C++ の _ReadWriteBarrier 組み込みのドキュメントで、次のテキストを見ています。
以前のバージョンの Visual C++ コンパイラでは、_ReadWriteBarrier および _WriteBarrier 関数はローカルでのみ適用され、呼び出しツリーの上位の関数には影響しませんでした。Visual C++ 2005 以降では、これらの関数は呼び出しツリー全体に適用されます。
関数内でバリアが何をするかは理解していますが、「呼び出しツリーの上」は、関数foo()
を呼び出す関数がバリアを含むbar()
かどうかを知ることができることを意味しているようです。bar()
これを可能にするために VC2005 で実際に変更されたものは何ですか... 呼び出し規約/ABI、コンパイラによって行われるいくつかのグローバル分析、または何ですか?
java - Java LockSupport メモリの一貫性
Java 6 API の質問です。呼び出しLockSupport.unpark(thread)
は、パーク解除されたばかりのスレッドからの戻りに対して発生前の関係を持っていますか? LockSupport.park
答えはイエスだと強く思いますが、Javadoc には明示的に言及されていないようです。
java - コンストラクターをチェーンするとき、JVM の暗黙的なメモリバリアはどのように動作しますか?
不完全に構築されたオブジェクトに関する以前の質問を参照して、2 つ目の質問があります。Jon Skeet が指摘したように、コンストラクターの最後には暗黙的なメモリ バリアがあり、final
フィールドがすべてのスレッドから見えるようになっています。しかし、コンストラクターが別のコンストラクターを呼び出すとどうなりますか。それらのそれぞれの終わりにそのようなメモリバリアがありますか、それとも最初に呼び出されたものの最後にのみありますか? つまり、「間違った」ソリューションが次の場合です。
正しいものは、ファクトリ メソッドのバージョンです。
以下も機能しますか?
更新:本質的な問題は、上記のプライベート コンストラクターthis()
を実際に呼び出すことが保証されていることです(この場合、意図した場所にバリアがあり、すべてが安全です)、またはプライベート コンストラクターがパブリックコンストラクターにインライン化される可能性はありますか? 1 つのメモリ バリアを節約するための最適化 (この場合、パブリック コンストラクターの最後までバリアはありません)?
のルールはthis()
正確にどこかに定義されていますか? そうでない場合は、チェーンされたコンストラクターのインライン化が許可されていると想定する必要があると思いますjavac
。
c++ - スレッド同期101
以前、私はいくつかの非常に単純なマルチスレッドコードを作成しましたが、実行中の途中でコンテキストスイッチが発生する可能性があることを常に認識していたため、共有変数へのアクセスを常に保護してきました。 CCriticalSectionクラスは、構築のクリティカルセクションに入り、破棄されます。私はこれがかなり攻撃的であることを知っており、クリティカルセクションに頻繁に、時にはひどく出入りします(たとえば、CCriticalSectionをよりタイトなコードブロック内に置くことができる関数の開始時)が、コードはクラッシュせず、十分に高速に実行されます。
仕事で私のマルチスレッドコードはよりタイトである必要があり、必要な最低レベルでのロック/同期のみです。
仕事で私はいくつかのマルチスレッドコードをデバッグしようとしていました、そして私はこれに出くわしました:
さて、m_bSomeVariable
Win32 BOOL(揮発性ではない)です。これは、私が知る限り、intとして定義されており、x86では、これらの値の読み取りと書き込みは単一の命令であり、コンテキストスイッチは命令境界で発生するため、必要はありません。この操作をクリティカルセクションと同期させるため。
この操作に同期が必要かどうかを確認するためにオンラインでさらに調査を行い、次の2つのシナリオを考え出しました。
- CPUがアウトオブオーダー実行を実装しているか、2番目のスレッドが別のコアで実行されており、更新された値が他のコアが確認できるようにRAMに書き込まれていません。と
- intは4バイトに揃えられていません。
ナンバー1は「volatile」キーワードで解決できると思います。VS2005以降では、C ++コンパイラはメモリバリアを使用してこの変数へのアクセスを囲み、使用する前に変数が常にメインシステムメモリに完全に書き込まれる/読み取られるようにします。
番号2確認できません。バイトアラインメントがなぜ違いを生むのかわかりません。x86命令セットはわかりませんがmov
、4バイトにアラインされたアドレスを指定する必要がありますか?そうでない場合は、指示を組み合わせて使用する必要がありますか?それは問題を引き起こすでしょう。
それで...
質問1:「volatile」キーワード(メモリバリアを使用し、このコードを最適化しないようにコンパイラにヒントを与えることを暗示する)を使用すると、プログラマはx86/x64変数の4バイト/8バイトを読み取り/間で同期する必要がなくなります。書き込み操作?
質問2:変数が4バイト/ 8バイトに整列されているという明示的な要件はありますか?
コードとクラスで定義された変数をさらに掘り下げました。
さて、私にはこれは過度に思えます。クリティカルセクションはプロセス間でスレッドを同期すると思ったので、ある場合はそのセクションに入ることができ、そのプロセス内の他のスレッドは実行できません。保護したい変数ごとにクリティカルセクションは必要ありません。クリティカルセクションにいる場合は、他に何も邪魔することはできません。
クリティカルセクションの外部から変数を変更できる唯一のことは、プロセスが別のプロセスとメモリページを共有し(それを実行できますか?)、他のプロセスが値を変更し始める場合だと思います。ミューテックスもここで役立ちます。名前付きミューテックスはプロセス間で共有されますか、それとも同じ名前のプロセスのみですか?
質問3:クリティカルセクションの分析は正しいですか?このコードはミューテックスを使用するように書き直す必要がありますか?他の同期オブジェクト(セマフォとスピンロック)を見てきましたが、ここの方が適していますか?
質問4:クリティカルセクション/ミューテックス/セマフォ/スピンロックはどこに最適ですか?つまり、どの同期問題に適用する必要があるかです。どちらかを選択すると、パフォーマンスが大幅に低下しますか?
そして、私たちがそれに取り組んでいる間、私は、スピンロックはシングルコアマルチスレッド環境では使用されるべきではなく、マルチコアマルチスレッド環境でのみ使用されるべきであることを読みました。それで、質問5:これは間違っていますか、そうでない場合は、なぜ正しいのですか?
返信ありがとうございます:)
c - アトミック参照カウント共有不変データにメモリバリアが必要ですか?
参照カウントを使用して管理し、SMP システム上のスレッド間でそれらを共有したい不変のデータ構造がいくつかあります。
リリースコードは次のようになります。
atomic_dec
その中にメモリバリアが必要ですか?もしそうなら、どのようなメモリバリアですか?
追加メモ: アプリケーションは PowerPC と x86 で実行する必要があるため、プロセッサ固有の情報を歓迎します。GCC アトミックビルトインについてはすでに知っています。不変性に関しては、refcount はオブジェクトの存続期間中に変化する唯一のフィールドです。
c++ - ミューテックス境界の周りでコンパイラを並べ替えますか?
独自の非インライン関数LockMutexとUnlockMutexがあり、これらは内部でブーストなどの適切なミューテックスを使用しているとします。LockMutexおよびUnlockMutexの呼び出しに関して、コンパイラーは他の操作を並べ替えないことをどのように知るのでしょうか。これらの関数を他のコンパイルユニットにどのように実装するかは、おそらくわかりません。
ps:ロックを解除するために、クラスのインスタンスを使用してロックを保持することになっています。例を簡略化するために、これは省略しました。