問題タブ [memory-model]
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++ - std::mutex との同期は std::atomic(memory_order_seq_cst) よりも遅いですか?
ミューテックスよりもアトミックを使用する主な理由は、ミューテックスが高価であるということですが、デフォルトのメモリモデルが でatomics
あるためmemory_order_seq_cst
、これは同じくらい高価ではありませんか?
質問: ロックを使用する並行プログラムは、ロックのない並行プログラムと同じくらい高速にできますか?
memory_order_acq_rel
もしそうなら、アトミックに使いたくない限り、努力する価値はないかもしれません。
編集:私は何かが欠けているかもしれませんが、各ロックも完全なメモリバリアでなければならないため、ロックベースはロックフリーよりも高速ではありません。しかし、ロックフリーを使用すると、メモリ バリアよりも制限の少ない手法を使用できます。
私の質問に戻りますが、ロックフリーは新しい C++11 標準に基づくロックよりも高速memory_model
ですか?
「パフォーマンスで測定するとロックフリー>=ロックベース」は本当ですか? 2 つのハードウェア スレッドがあるとします。
編集 2: 私の質問は、進行の保証に関するものではありません。おそらく、コンテキスト外で「ロックフリー」を使用している可能性があります。
基本的に、共有メモリを持つ2つのスレッドがあり、必要な唯一の保証は、一方のスレッドが書き込みを行っている場合、もう一方のスレッドが読み書きできないということです。私の仮定は、単純なアトミックcompare_and_swap
操作の方がミューテックスをロックするよりもはるかに高速であるということです.
1 つのスレッドが共有メモリにまったく触れない場合、理由もなく何度もロックとロック解除を繰り返すことになりますが、アトミック操作では毎回 1 CPU サイクルしか使用しません。
コメントに関しては、競合がほとんどない場合、スピンロックとミューテックスロックは大きく異なります。
c# - メモリ モデル: ストア リリースとロード アクワイアの並べ替えを防止する
Java の volatile とは異なり、.NET の volatile では、別の場所からの後続の volatile 読み取りを使用して、volatile 書き込みの順序を変更できることが知られています。問題 MemoryBarier
がある場合は、それらの間に配置することをお勧めします。またはInterlocked.Exchange
、揮発性書き込みの代わりに使用できます。
機能しますがMemoryBarier
、高度に最適化されたロックフリー コードで使用すると、パフォーマンスが低下する可能性があります。
少し考えて、ある考えに至りました。私が正しい道を歩んだかどうか、誰かに教えてもらいたい。
したがって、アイデアは次のとおりです。
これら 2 つのアクセス間での並べ替えを防止したいと考えています。
.NET MM から、次のことがわかります。
書き込みと読み取りの間の不要な並べ替えを防ぐために、書き込み先の変数からダミーの volatile 読み取りを導入します。
このような場合、両方が同じ変数にアクセスするため、 B を A で並べ替えることができず、 CをBで並べ替えることができません。これは、2 つの揮発性読み取りを相互に並べ替えることができず、推移的にCをAで並べ替えることができないため です。
そして質問:
私は正しいですか?そのダミーの揮発性読み取りを、そのようなシナリオの軽量メモリバリアとして使用できますか?
java - 因果的一貫性は順序的一貫性とどのように異なりますか?
シーケンシャル一貫性では、すべてのプロセスをシーケンシャルに処理する必要があることを理解しています。例えば:
したがって、x=1、z=5、y=2、p=3 または z=5、p=3、x=1、y=2 を得ることができます。しかし、重要なのは、p は z が実行された後にのみ実行できるということです。正しいですか?
因果的一貫性についてはどうですか?そこに違いは見られません。Java や C で書かれたスケッチやコードは素晴らしいでしょう。ありがとうございました。
x86 - 保護されたフラット モデルの CS と DS の値
保護されたフラット モデルの特定のプロセスの CS および DS セグメント レジスタは同じ値を保持しますか?
つまり、同じプログラム内で次のコード シーケンスを実行し
mov dword ptr [0x7fffffff], ebx
、
org 0x7fffffff
...some instruction ...
同じ場所を指しますか?(もしそうなら、保護されたフラット モデルで CS と DS を分離する目的は何ですか?) ありがとうございます。
c++ - アトミック ルールの緩和の (わずかな) 違いは何ですか?
Herb Suttersの「原子兵器」に関する優れた講演を見た後、 Relaxed Atomicsの例について少し混乱しました。
私は、C++ メモリ モデル(SC-DRF = データ競合のない連続整合性)のアトミックが、ロード/読み取りで「取得」を行うことを理解しました。
std::memory_order_seq_cst
ロード[およびストア]のデフォルトはであるため、2つは同じであることを理解しています。
これまでのところ、Relaxed Atomics は使用されていません (話を聞いた後は、Relaxed Atomics を使用することは決してありません。約束します。しかし、誰かに尋ねられたら、説明する必要があるかもしれません...)。
しかし、なぜ私が使用すると「リラックスした」セマンティクスなのですか
loadはを取得していて解放していないのに、これが(1)
and と異なるのはなぜ(2)
ですか? ここで実際にリラックスしているのは何ですか?
私が考えることができる唯一のことは、loadがacquireを意味すると誤解したことです。そして、それが真であり、デフォルトseq_cst
が両方を意味する場合、それは完全なフェンスを意味するのではないでしょうか? その命令を上に渡すことも、下に移動することもできませんか? 私はその部分を誤解していたに違いありません。
[そしてストアとリリースのために対称的に]。
java - 揮発性と同期を使用する場合、さまざまなスレッドにフラッシュまたはパブリッシュされるメモリの範囲はどのくらいですか?
この質問は、メモリの可視性のみに関連しており、発生前および発生後ではありません。Java には、あるスレッドのメモリへの変更が別のスレッドから見えるようにすることを保証する 4 つの方法があります。(参照http://gee.cs.oswego.edu/dl/cpj/jmm.html )
- 書き込みスレッドが同期ロックを解放し、その後、読み取りスレッドが同じ同期ロックを取得します。
- フィールドが volatile として宣言されている場合、書き込みスレッドがさらにメモリ操作を実行する前に、そのフィールドに書き込まれた値はすべてフラッシュされ、書き込みスレッドによって可視になります (つまり、当面の目的のためにすぐにフラッシュされます)。
- スレッドがオブジェクトのフィールドに初めてアクセスすると、フィールドの初期値か、他のスレッドによって書き込まれた後の値が表示されます。
- スレッドが終了すると、書き込まれたすべての変数がメイン メモリにフラッシュされます。
Java Concurrency in Practice によると、そのような質問に関する聖書:
volatile 変数の可視性効果は、volatile 変数自体の値を超えて拡張されます。スレッドAが揮発性変数に書き込み、続いてスレッドBが同じ変数を読み取ると、揮発性変数に書き込む前にAに表示されていたすべての変数の値は、揮発性変数を読み取った後にBに表示されます。
揮発性の質問
これは、 AからCではなく A から B にメモリをフラッシュする方法を知るために、JVM が実際に volatile 変数の読み取りと書き込みを追跡することを意味しますか? したがって、 Aが変数に書き込み、後でCが変数から読み取り、その後Bが変数から読み取り、フラッシュはAとBおよびAとCの間でスレッドごとに行われますが、BとCは行われませんか? または、スレッドに関係なく、キャッシュされたすべてのメモリがフラッシュされることを意味しますか? volatile 変数のみがフラッシュされますか、それともキャッシュされたメモリはすべてフラッシュされますか?
同期質問
キーワード flushing の場合synchronized
、ロック内で更新されたメモリのみが他のスレッドに公開されることが保証されます。これは、次のコードで を実行している 2 つのスレッドがmethod()
、同期ブロックを離れてstaticVar2
他のスレッドにフラッシュすることを意味しますが、そうではありません staticVar1
。正しいですか?
また、 では、別のスレッドが実行されている場合method2()
、同期をdifferentLock
行うと、事前発生後発生の問題が発生する可能性がありますmethod()
。ただし、問題は視認性です。スレッドAが実行さmethod
れ、その後スレッドBが実行された場合、2 つのスレッドが同じロックを介して同期していなくても、AからBに発行されmethod2()
た値は?staticVar2
静的な質問
が他のスレッドに更新されない場合staticVar1
、プログラム内のすべての静的変数は宣言を必要とするか、ブロックvolatile
内でのみアクセスする必要があるようです。synchronized
かなり厳しいように見えますが、正しいですか?私の時代に、同期されていない静的変数がたくさんあるのを見たことがあります。
要約すれば
- 揮発性の読み取り/書き込みは、すべてのメモリをすべてのスレッドにフラッシュしますか、それともアクセスしている 2 つのスレッド間のみにフラッシュしますか? 答えが何であれ、すべてのメモリがフラッシュされるか、揮発性変数のみがフラッシュされますか?
- 同期されたブロックを終了するときに変更されたすべてのメモリがフラッシュされますか、それともブロック内で変更されたメモリだけですか? すべてのメモリがフラッシュされていない場合、値を確認するには、スレッドが同期するロック オブジェクトが同じである必要がありますか (つまり、ロック オブジェクトはメモリの可視性に何らかの影響を与えますか)?
- 2 つのスレッドがアクセスするすべての静的変数を同期する必要がありますか?
c++ - C++ 11 のアトミックは、コンパイラが共有変数から再読み込みするのを防ぎますか?
私は Herb の素晴らしい「原子兵器」の講演を 2 回目で探しており、全記憶モデル / 逐次的一貫性の物語を経る概念に頭を悩ませようとしています。概念レベルで気になることが 1 つあります。この話から得た教訓の 1 つは、atomics を使用することで、他の方法ではコンパイラーが検出できないスレッド間の相互作用について、コンパイラーに「ヒント」を与えることができるということです。
そこで、次のシナリオについて心配し始めました。
この場合、Hans Bohem が「「無害な」データ競合を含むプログラムを誤ってコンパイルする方法」で指摘したように (変数名は上記のスニペットに合わせて調整されています):
2 つのテストの間に local_copy_of_shared_var を含むレジスタをスピルする必要があるとコンパイラが判断した場合、値の格納を回避し (結局のところ、これは単に shared_var のコピーにすぎません)、代わりに単純に shared_var の値を再読み取りすることを決定する可能性があります。 local_copy_of_shared_var を含む 2 番目の比較。
[...] 核となる問題は、変数値は明示的な代入なしでは非同期に変更できないという仮定をコンパイラが利用することから生じます。私たちの設定のようにデータ競合が言語仕様で許可されていない場合、そのような仮定は完全に正当です。データ競合がなければ、このような非同期変更は不可能です
ここで、アトミック (デフォルトの seq_cst メモリー順序付け) はデータ競合がないことを保証する必要があり、それらは異なるスレッド間でそのような変数に相互作用があるというコンパイラーへの「ヒント」であるため、前述のアトミックを使用すると主張することができますスニペットは、コンパイラがshared_varからそのような「再読み取り」を挿入するのを防ぎ、代わりにlocal_copy_of_shared_varを「ワンショット」スナップショットと見なして、2 つのテスト間の矛盾を回避しますか?
常識に基づいて、ここでアトミックを使用するだけで、2 つのテスト間でlocal_copy_of_shared_varが更新されないようにコンパイラが対策を講じることが保証されるとは思わないため、私の推論には何か問題があると思います。一方、Herb が講演で述べているように、メモリ モデルは、アトミックを使用する場合にコンパイラによって偽のメモリ操作が追加されないことを保証するようになりました。 "安全"。私は非常に混乱しており、コミュニティからの意見を聞きたいと思っています。私の推論にバグがある場合は、おそらく修正してもらいたいと思っています。