問題タブ [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.

0 投票する
1 に答える
582 参照

vb.net - フィールドを逆参照するときにメモリ バリア (.net x86 または x64) は必要ですか?

次のようなコードで、Proc1 と Proc2 が異なるプロセッサで同時に実行される場合、ThingVal2 が 5 以外の値 (ゼロなど) を取得することは可能ですか?

IA64 のような弱いモデルでは、Proc2 が ThingRef が変更されたと認識しても、Thing2 のフィールド X が変更されたと認識しない可能性が実際にあることを私は知っています。x86 または x64 で実行されている .Net アプリケーションにそのリスクは存在しますか? Proc1 が SimpleThing の新しいインスタンスを作成し、その X フィールドを 5 に設定し、ThingRef をそれを指すように設定した場合、危険を回避するにはそれで十分であるか、または新しい Thing がキャッシュ ラインに割り当てられる可能性があります。 Proc2 スレッドがアクセスした他の何かと共有されましたか?

マルチスレッド コードの一般的なパラダイムは、不変オブジェクトを構築し、それを指す可変参照を設定することです (おそらく Interlocked.CompareExchange を使用します)。x86/x64 では、スレッドに関係なく不変型を読み取ることは常に安全ですか?それとも問題を引き起こす可能性がありますか? 後者の場合、信頼できる動作を保証するためにvb.netで推奨される方法は何ですか?

また、そのような問題が発生しない方法でコードを実行する必要があることを指定する方法はありますか?

0 投票する
3 に答える
2676 参照

assembly - x86 での順次一貫性のあるアトミック ロード

x86 でのシーケンシャル コンシステント ロード操作に興味があります。

コンパイラーによって生成されたアセンブラーのリストを見る限り、x86 では単純なロードとして実装されていますが、私が知る限り、プレーンなロードはセマンティクスを取得することが保証されていますが、プレーンなストアは解放されることが保証されています。

シーケンシャル コンシステント ストアはロックされた xchg として実装され、ロードはプレーン ロードとして実装されます。私には奇妙に聞こえますが、これを詳しく説明していただけますか?

追加した

ロックされた xchg でストアが行われている限り、順次一貫性のあるアトミック ロードを単純な mov として実行できることがインターネットで見つかりましたが、証拠もドキュメントへのリンクもありませんでした。

0 投票する
1 に答える
179 参照

c# - フル メモリ バリアと ExclusiveReceiverGroup

次のコードを使用します。

totalSum += computeResult.Result の周りに完全なメモリ バリアを生成する必要がありますか? DispatcherQueue は Dispatcher を使用しないため、ExclusiveReceiverGroup のレシーバー登録のハンドラーはスレッド プールによって呼び出されます。スレッド プールが呼び出すコールバックのメモリ バリアを生成することを読みましたが、それはコールバック参照自体の鮮度を保証するだけですか?

ExclusiveReceiverGroup は他のコードと同時に実行されないため、computerResult.Result による totalSum のインクリメントはアトミックである必要はありません。Interlocked.Add が完全なフェンスを暗黙的に生成することは知っていますが、それを使用せずに逃げることができるかどうかを確認したいだけです。

これは理論上の問題です。上記のコード例のようなコードは実際にはありませんし、そのようなコードのユースケースもありません。したがって、「念のため Interlocked.Add を使用する」という回答は避けたいと思います。これは、「何か新しいことを学びましょう」という質問です。

0 投票する
1 に答える
1163 参照

c++ - コンパイラと CPU の並べ替え

私はこの次の状況を持っています。

私の質問は、CPU またはコンパイラのいずれかがSetValues()関数の行を並べ替える可能性はありますか?

0 投票する
2 に答える
2509 参照

c++ - C ++ 0xのフェンス、一般的にアトミックまたはメモリのみを保証

C ++ 0xドラフトには、CPU /チップレベルのフェンスの概念とは非常に異なるように見えるフェンスの概念があります。つまり、Linuxカーネルの人がフェンスに期待することを言います。問題は、ドラフトが本当に極端に制限されたモデルを暗示しているのか、それとも言い回しが貧弱で実際に真のフェンスを暗示しているのかということです。

たとえば、29.8フェンスでは、次のように記述されます。

リリースフェンスAは、AがXの前にシーケンスされ、XがMを変更し、YがBの前にシーケンスされ、Yが値を読み取るように、両方が何らかのアトミックオブジェクトMで動作するアトミック操作XおよびYが存在する場合、取得フェンスBと同期します。 Xによって書き込まれた値、または仮想のリリースシーケンスXのいずれかのサイドエフェクトによって書き込まれた値は、リリース操作の場合に先頭になります。

これらの用語atomic operationsとを使用しatomic objectます。ドラフトで定義されているそのような不可分操作とメソッドがありますが、それはそれらだけを意味するのでしょうか?リリースフェンスはストアフェンスのように聞こえます。フェンスの前にすべてのデータの書き込みを保証しないストアフェンスはほとんど役に立たない。ロード(取得)フェンスとフルフェンスについても同様です。

それで、C ++ 0xの適切なフェンスと言い回しのフェンス/バリーは非常に貧弱ですか、それとも説明されているように非常に制限されている/役に立たないのですか?


C ++に関して、私がこの既存のコードを持っているとしましょう(GCCで__sync_synchronizeを使用する代わりに、フェンスが現在高レベルの構造として利用可能であると仮定します):

a、b、cが、プラットフォーム上にアトミックコピーを持つサイズであると想定します。上記は、cこれまでにのみ割り当てられることを意味します9a==5スレッドBがいつ表示されるかは関係ありませんが、スレッドBが表示されるときにも表示されることに注意してくださいb==9

同じ関係を保証するC++0xのコードは何ですか?


答え:私の選んだ答えとすべてのコメントを読むと、状況の要点がわかります。C ++ 0xは、フェンスでアトミックを使用するように強制しているように見えますが、通常のハードウェアフェンスにはこの要件がありません。多くの場合、とがである限り、これを使用して並行アルゴリズムを置き換えることができsizeof(atomic<T>) == sizeof(T)ますatomic<T>.is_lock_free() == true

残念ながら、それはis_lock_freeconstexprではありません。これにより、で使用できるようになりますstatic_assert。ロックの使用に退化することは一般的に悪い考えです。ミューテックスをatomic<T>使用するアトミックアルゴリズムは、ミューテックスで設計されたアルゴリズムと比較して、ひどい競合の問題を抱えています。

0 投票する
1 に答える
733 参照

c# - ノンブロッキング同期 (MemoryBarrier)

Non-Blocking Synchronizationで指定されたプログラムを次のように変更しました。

この記事では、they ensure that if B ran after A, reading _complete would evaluate to true.>> それらはメモリバリアを意味すると述べています。

メモリバリアを取り除いても、出力に変化はありません。if 条件が真であることを確認していません。

私はそれを間違った方法で解釈しましたか?

ありがとう。

0 投票する
1 に答える
1702 参照

multithreading - __faststorefenceの動作は何ですか?

この質問に関しては、x86とx86-64にのみ興味があります。

MSVC 2005の場合、__ faststorefenceのドキュメントには、「先行するすべてのストアが後続のストアの前にグローバルに表示されることが保証されます」と記載されています。

MSVC 2008および2010では、次のように変更されました。 「ロードメモリ参照とストアメモリ参照の両方を含む、以前のすべてのメモリ参照が、後続のメモリ参照の前にグローバルに表示されることを保証します。」

後者の書き方は、私の意見では、これは古いストアの前にCPUがロードを並べ替えることもブロックすることを意味します。これは最初の定義とは異なります。つまり、本質的には、非一時ストアと古いストアのブロックまたは並べ替えのみを処理することです(他の唯一の並べ替えx86(-64)は処理します)。

ただし、ドキュメントは矛盾しているように見えます。「x64プラットフォームでは、このルーチンはsfence命令よりも高速なストアフェンスである命令を生成します。x64プラットフォームでは_mm_sfenceの代わりにこの組み込み型を使用してください。」

これは、それがまだsfenceのような機能を持っていることを意味し、したがって、ロードはまだ古いストアで並べ替えることができます。それで、それはどれですか?誰かが私の混乱を解消できますか?

PS:この関数のGCCバージョンを探していて、出くわしましlong local; __asm__ __volatile__("lock; orl $0, %0;" : : "m"(local));たが、32ビットコードからのものだと思います。64ビットアナログは何でしょうか?

0 投票する
3 に答える
4675 参照

java - javaの揮発性変数とメモリバリア

リンクされたノードで構成されるデータ構造があります。これは単純な LinkedList と考えることができます。リストの各ノードは、何らかの値と、他のノードを指す次のフィールド、または最後のノードの場合は null で構成されます。最初のノードはルートとして機能し、値はなく、次のノードを指すだけです。他のすべてのノードは実質的に不変であり、特定の状況に関連して構造体が破棄されない限り、一度作成されると値も次のフィールドも存続期間中に変更されません。

1 つ (1 つだけ) のスレッドが新しいノードをリストの先頭に追加します。これは、新しいオブジェクトを構築し、そのフィールドを設定し、次のフィールドをルートが指すオブジェクトに設定し、ルートの次のフィールドをこの新しいノードに設定することによって実現されます。

他のノードは、読み取りのみを実行して構造をブラウズします。ルート ノードへの参照があり、探しているものが見つかるか、リストの最後に到達するまで、他のノードを通過します。

私の質問は、次のフィールドを揮発性にするだけで十分ですか? 私の Java メモリ モデルの理解から、新しいノードを追加するときにメイン スレッド (新しいノードを追加するスレッド) が揮発性書き込みを実行する場合、すべてが正常に同期され、不整合は発生しません。

また、x86 アーキテクチャで揮発性変数の読み取りがパフォーマンスの低下を引き起こさないと仮定するのは正しいですか? 他のスレッドは次のフィールドを読み取る構造体を頻繁にブラウズするため、これがメモリバリアなどなしに自由に実行できることが重要です。

また、もうひとつ気になることがあります。構造をブラウズするスレッドは、いくつかの追加ノードも保持します。これらのノードは完全にスレッド ローカルであり、ノードを作成したスレッドのみが使用し、まったく共有されません。これらの追加ノードでは、次のフィールドが揮発性である必要はありません。さらに、volatile next フィールドを設定すると、望ましくないパフォーマンスの低下を引き起こすメモリ バリアが発生します。これを回避する方法はあるのだろうか。理想的には、次のフィールドが揮発性フィールドとして機能する場合と、通常のフィールドとして機能する場合があります;) または、完全に制御でき、必要なときにいつでも自分でメモリバリアを発行できれば完璧です。

編集:

また、これらすべての書き込みを別の揮発性変数に何らかの方法で同期することは可能でしょうか? たとえば、他の完全に無関係な静的変数はありますか? 揮発性書き込みは保留中のすべての書き込みをフラッシュするため、更新スレッドがすべての作業を行った後に、次のフィールドが揮発性ではなく、代わりに別の揮発性変数が書き込まれる可能性はありませんか?

リレーションの前に発生することはなく、以前の書き込みが並べ替えられる可能性があるため、私にはあまり安全ではないようです。次のフィールドの割り当ては、値フィールドの割り当てで再順序付けされる可能性があり、反復スレッドが一貫性​​のないオブジェクトの状態を観察することにつながります。

しかし、そのような安全なスキームを考え出すことは可能でしょうか? これはどう:

更新スレッドは、最初に新しいオブジェクトを構築し、その値フィールドを初期化し、その次のフィールドをルート ノードが指すノードに設定し、いくつかの静的変数で揮発性書き込みを実行し、ルート ノードの次のフィールドを新しく作成されたノードに設定します。

0 投票する
1 に答える
779 参照

c# - ロック ヘルパーのスレッド セーフな使用法 (メモリ バリアに関する)

usingロックヘルパーとは、ステートメントを介してロックを実装できる使い捨てオブジェクトを指しています。たとえば、Jon Skeet の MiscUtilSyncLockのクラスの典型的な使用法を考えてみましょう。

ここで、次の使用法を検討してください。

私の質問はこれです -exampleはあるスレッドで作成されConcurrentMethod、別のスレッドで呼び出されるため、ConcurrentMethodのスレッドはコンストラクターでの の割り当てを忘れることはできませんでした(_padockスレッドのキャッシュ/読み書きの並べ替えのため)。自体)?NullReferenceException_padLock

Monitor/によるロックにはメモリバリアの利点があることは知っていlockますが、これらのようなロックヘルパーを使用すると、そのようなバリアが保証される理由がわかりません。その場合、私が理解している限り、コンストラクターを変更する必要があります。

出典:マルチスレッド アプリにおけるローロック テクニックの影響の理解

EDIT Hans Passant は、スレッドの作成がメモリバリアを意味することを示唆しています。それではどうですか:

現在、スレッドは必ずしも作成されているわけではありません...

0 投票する
3 に答える
4620 参照

c# - メモリーバリアジェネレーター

Joseph Albahari の threading tutorialを読むと、メモリバリアの生成元として次のことが言及されています。

  • C# のlockステートメント ( Monitor.Enter/ Monitor.Exit)
  • Interlockedクラスのすべてのメソッド
  • スレッド プールを使用する非同期コールバック — これらには、非同期デリゲート、APM コールバック、およびタスクの継続が含まれます。
  • シグナリング構造の設定と待機
  • タスクの開始や待機など、シグナル伝達に依存するものすべて

さらに、Hans Passant と Brian Gideonは次のことを追加しました(いずれも前のカテゴリのいずれにも当てはまらないと仮定します)。

  • スレッドの開始またはウェイクアップ
  • コンテキスト スイッチ
  • Thread.Sleep()

私はこのリストが完全であるかどうか疑問に思っていました (完全なリストを実際に作成することさえできれば)

編集の追加が提案されました:

  • 揮発性 (読み取りは取得フェンスを意味し、書き込みは解放フェンスを意味します)