タグ付けされた質問 「memory-barriers」

1
Javaで使用されるメモリフェンスとは何ですか?
バージョン9でJava SEに追加された新しいクラスSubmissionPublisher(Java SE 10のソースコード、OpenJDK | docs)がどのように実装されているかを理解しようとしているVarHandleときに、以前は知らなかったいくつかのAPI呼び出しに遭遇しました。 fullFence、acquireFence、releaseFence、loadLoadFenceとstoreStoreFence。 特にメモリバリア/フェンスの概念に関していくつかの調査を行った後(以前に聞いたことがありますが、使用していなかったため、セマンティクスにはまったく不慣れでした)、それらの目的について基本的な理解ができたと思います。それにもかかわらず、私の質問は誤解から生じる可能性があるため、私はそもそもそれが正しく行われたことを確認したいと思います。 メモリバリアは、読み取りおよび書き込み操作に関する制約を並べ替えています。 メモリバリアは、読み取りまたは書き込み、あるいはその両方に制約を設定するかどうかに応じて、単方向および双方向のメモリバリアという2つの主要なカテゴリに分類できます。 C ++はさまざまなメモリバリアをサポートしていますが、これらはが提供するバリアとは一致しませんVarHandle。ただし、で利用可能なメモリバリアの一部は、対応するC ++メモリバリアと互換性のある順序付け効果をVarHandle提供します。 #fullFence と互換性があります atomic_thread_fence(memory_order_seq_cst) #acquireFence と互換性があります atomic_thread_fence(memory_order_acquire) #releaseFence と互換性があります atomic_thread_fence(memory_order_release) #loadLoadFenceそして、#storeStoreFence互換性のあるC ++カウンターパートを持っていません 詳細に関してはセマンティクスが明らかに異なるため、ここでは互換性という言葉は本当に重要なようです。たとえば、すべてのC ++バリアは双方向ですが、Javaのバリアはそうではありません(必須)。 ほとんどのメモリバリアにも同期効果があります。これらは特に、使用されているバリアタイプと、他のスレッドで以前に実行されたバリア命令に依存します。バリア命令が持つ完全な影響はハードウェア固有なので、高レベル(C ++)のバリアを使用します。たとえば、C ++では、バリア解放命令の前に行われた変更は、バリア取得命令を実行するスレッドに表示されます。 私の仮定は正しいですか?もしそうなら、私の結果の質問は: で使用可能なメモリバリアはVarHandle、何らかの種類のメモリ同期を引き起こしますか? それらがメモリ同期を引き起こすかどうかに関係なく、Javaで何を並べ替える制約が役立つのでしょうか?Javaメモリモデルは、揮発性フィールド、ロック、またはVarHandle操作など#compareAndSetが関係する場合の順序付けに関して、すでにいくつかの非常に強力な保証を提供しています。 例を探している場合:前述BufferedSubscriptionのSubmissionPublisher(上記のリンクされたソース)の内部クラスは、1079行に完全なフェンスを設定しました(関数growAndAdd;リンクされたWebサイトはフラグメント識別子をサポートしていないため、CTRL + Fを使用するだけです) )。しかし、それが何のためにあるのか私には分かりません。

4
C ++ 11でStoreLoadバリアを実現する方法は?
古典的な問題の変形を解決する移植可能なコード(Intel、ARM、PowerPC ...)を記述したいと思います。 Initially: X=Y=0 Thread A: X=1 if(!Y){ do something } Thread B: Y=1 if(!X){ do something } ここでの目標は、両方のスレッドがやっているような状況を避けるためですsomething。(どちらも実行しなくても問題ありません。これは1回だけ実行するメカニズムではありません。)以下の私の推論に欠陥がある場合は、修正してください。 私は次のようにmemory_order_seq_cstアトミックstoresおよびloads を使用して目標を達成できることを認識しています。 std::atomic<int> x{0},y{0}; void thread_a(){ x.store(1); if(!y.load()) foo(); } void thread_b(){ y.store(1); if(!x.load()) bar(); } {x.store(1), y.store(1), y.load(), x.load()}イベントにはいくつかの単一の合計順序が必要であり、プログラムの順序「エッジ」に同意する必要があるため、これは目標を達成します。 x.store(1) 「TOは前に」 y.load() y.store(1) 「TOは前に」 x.load() foo()呼び出された場合、追加のエッジがあります: y.load() 「前に値を読み取る」 y.store(1) bar()呼び出された場合、追加のエッジがあります: …

1
C11 Atomic Acquire / Releaseおよびx86_64ロード/ストアの一貫性の欠如?
C11標準のセクション5.1.2.4、特にリリース/取得のセマンティクスに苦労しています。私は、https://preshing.com/20120913/acquire-and-release-semantics/(他のものの中でも)が次のように述べていることに注意します。 ...リリースセマンティクスは、プログラムの順序でそれに先行する読み取りまたは書き込み操作による書き込みリリースのメモリの並べ替えを防ぎます。 したがって、次の場合: typedef struct test_struct { _Atomic(bool) ready ; int v1 ; int v2 ; } test_struct_t ; extern void test_init(test_struct_t* ts, int v1, int v2) { ts->v1 = v1 ; ts->v2 = v2 ; atomic_store_explicit(&ts->ready, false, memory_order_release) ; } extern int test_thread_1(test_struct_t* ts, int v2) { int v1 …
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.