問題タブ [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.
linux - スピンロックには本当に DMB が必要ですか?
私はデュアル Cortex-A9 システムで作業しており、スピンロック関数が DMB を使用する必要がある理由を正確に理解しようとしています。マージ ストア バッファーがフラッシュされている限り、ロック値はロック解除コアの L1 で終了し、SCU は他のコアの L1 の値を無効にするか更新する必要があるようです。これは、一貫性と安全なロックを維持するのに十分ですか? とにかく、STREX はマージ ストア バッファをスキップしないのでしょうか。つまり、フラッシュは必要ないのでしょうか?
DMB は、特にシステム ドメインにデフォルト設定されているため、鈍いハンマーのように見えます。これは、コストがかかる可能性があるメイン メモリへの書き込みを意味する可能性が高いためです。
smp_mb を適切に使用しないドライバーの回避策として、ロック内の DMB はありますか?
現在、パフォーマンス カウンターに基づいて、システム サイクルの約 5% が DMB によるストールで消失していることがわかります。
android - Java プログラムの ARM マルチコア ペナルティ
マルチコア ARM チップとシングル コア チップで Dalvik+JIT を実行するとペナルティがあるのでしょうか?
たとえば、Android システム ビルドでマルチコア サポートを無効にし、電話全体を単一の CPU コアで実行すると、シングルスレッドの Java ベンチマークを実行したときにパフォーマンスが向上しますか?
マルチコアでのメモリバリアと同期のコストはいくらですか?
シングル コアの電話とデュアル コアの電話のシングル スレッドのベンチマーク スコアを見たのを漠然と覚えているので、質問しています。Mhz がほぼ同じである限り、2 つの電話に大きな違いはありません。デュアルコア電話の速度低下を予想していました....
c++ - メモリバリア:初期化書き込みがワーカースレッドに確実に表示されるようにするにはどうすればよいですか?
私はメモリバリア/フェンスを使用したプログラミングにかなり慣れていません。セットアップの書き込みが、後で他のCPUで実行されるワーカー関数に表示されることをどのように保証できるのか疑問に思いました。たとえば、次のことを考慮してください。
その後(同時にではなく)、何度も何度も実行します。
CPU 2では、mySetup
が1の場合、 sheep
9であることが保証されますがmySetup
、0ではないことをどのように保証できますか?
これまでのところ、CPU 2で1になるまでスピンウェイトすることしか考えられません。しかし、スピンウェイトが最初に呼び出されたsetup
ときに待機するだけでよいことを考えると、これは非常に醜いようです。ManipulateSheep()
確かにもっと良い方法があるに違いありませんか?
初期化解除コードには対称的な問題もあることに注意してください。たとえば、存続期間中にメモリを割り当てるロックフリーのデータ構造を作成しているとします。デストラクタでは(すべてのスレッドがメソッドの呼び出しを終了したと仮定して)、すべてのメモリの割り当てを解除する必要があります。つまり、デストラクタを実行しているCPUが最新の変数値を持つ必要があります。デストラクタはそれをチェックするために「最新の」状態が何であるかを知る方法がないため、そのシナリオでスピン待機することさえできません。
編集:私が求めているのは、「すべてのストアが他のCPUに伝播するのを待つ」(初期化の場合)および「すべてのストアがCPUに伝播するのを待つ」(非初期化の場合)と言う方法はありますか?
c - そのような場合の軽量(最も)軽量のGCCメモリバリアは何ですか?
私は次のCコードを持っています:
コードはロックによって保護されていません(他の人はただ読んdata
で)、の更新前に保存されindex
ていることを確認したいと思います。このコードの周りには他の変数のメモリ書き込みと読み取りがありますが、それらは重要ではないので、GCCはそれらを自由に並べ替えることができます(最適化のためにそうすることを願っています)。の順序を保証するだけで十分です。この目標を達成するには、どのように実装する必要がありますか?data[index]
index
data[index]
index
a_write_memory_barrier()
c++ - std::mutex による解放と取得
これは C++ 標準に関する質問です。私はドラフト標準にしかアクセスできないため、これが公式のものと異なる場合はお詫びします. また、これがどのように機能するかを誤解している場合は、お気軽に修正してください。
1 つは文字列への書き込み、もう 1 つはその文字列の内容のコピーを作成する 2 つのスレッドがあるとします。一般に、ロックには RAII クラスを使用する必要があるstd::mutex myMutex;
ことはわかっています。例をより明確にするために、lock と unlock を明示的に使用しました。
私の理解では、これがスレッド間で確実に機能するためには、スレッド 1が文字列を設定した後にリリース操作を実行し、スレッド 2が文字列を読み取る前に取得を実行する必要があります。
C++11 のドラフト標準を読んでも、これを行うと述べているものは何も見えませんがstd::mutex
、それが期待されていること、またはミューテックスが何の役にも立たないことは明らかです。
誰かが私に関連セクションを見てもらうことができますか? 標準の文言は、カジュアルな読者にはしばしば明確ではありません:)
gcc - コンパイル時間の障壁 - コンパイラ コードの並べ替え - gcc と pthreads
私の知る限り、メモリバリアとして機能する pthread 関数があります (たとえば、ここでは clarifications -on-full-memory-barriers-involved-by-pthread-mutexes )。しかし、コンパイル時のバリアについてはどうでしょうか。つまり、コンパイラ (特に gcc) はこれを認識していますか?
言い換えれば - たとえば - gcc が並べ替えを実行しない pthread_create() の理由ですか?
たとえば、コードでは次のようになります。
再注文が行われないことは確実ですか?
さまざまな関数からの呼び出しはどうですか:
fun() もコンパイル時間の障壁ですか (pthread_create() を想定)?
異なる翻訳単位の関数はどうですか?
一般的な gcc および pthreads の動作仕様に関心があることに注意してください。必ずしも x86 固有ではありません (さまざまな組み込みプラットフォームに焦点を当てています)。
また、他のコンパイラ/スレッド ライブラリの動作には興味がありません。
multithreading - エミュレーターはメモリバリア (暗黙的および明示的) の変換をどのように処理しますか?
ソース アーキテクチャとターゲット アーキテクチャが異なると仮定すると、エミュレータはメモリ バリアをどのように効率的に変換するのでしょうか? 一般に、最新のエミュレーターは JIT を使用してソースISAからターゲット ISA に変換することを知っていますが、どのコードが複数のプログラム カウンターによって到達可能であり、どのコードが到達可能でないかを知り、どの命令を並べ替えても安全かを知ることは非常に難しいと思われます。 (ISAの違いにより、JITが効率的なものを生成するために必要になる可能性があります)、そうではないものは非常にトリッキーに思えます。
命令ストリームで明示的なメモリ バリアを見つけることさえ保証されていません。たとえば、x86 の多くの人々は、整列されたワード書き込みがアトミックであることを信頼しています。エミュレーターは保守的に、整列されたすべてのワード書き込みを並べ替えることができないと想定していますか? これは潜在的に巨大なオーバーヘッドのように思われるため、この種の問題に取り組むための既知の分析があるかどうか疑問に思います。
c++ - FIFO エンキューにメモリ バリアを追加する必要がありますか?
リンク リストを使用して非ロック FIFO を実装しています。
Enqueue
FIFO の基本は次のとおりです。
シングルスレッドの場合、メモリバリアを追加する必要があるかどうか疑問に思っています(つまり、コンパイラ/プロセッサは上記の2行の順序を再配置できますか?)。マルチスレッドの場合 (つまり、シングル リード シングル ライターの場合と同じくらい単純) はどうでしょうか。
編集: hereによると、これはデータの反依存関係のケースであり、ステートメントを並べ替えるべきではありません。したがって、CPUは常に指定された順序でメモリにアクセスする必要があると思います。そうですか?
c++ - メモリオーダリングはユニプロセッサ上の他のスレッドに表示されますか?
最近のCPUアーキテクチャでは、パフォーマンスの最適化が採用されているため、実行が順不同になる可能性があります。シングルスレッドアプリケーションでは、メモリの並べ替えも発生する可能性がありますが、プログラムの順序でメモリにアクセスしたかのように、プログラマーには見えません。また、SMPの場合、ある種のメモリ順序を強制するために使用されるメモリバリアが救いの手を差し伸べます。
よくわからないのは、ユニプロセッサでのマルチスレッドについてです。次の例を考えてみましょう。スレッド1が実行されると、tof
のストアがtoのストアの前に発生する可能性がありx
ます。f
が書き込まれた後、および書き込まれる直前にコンテキストスイッチが発生するとしますx
。これでスレッド2が実行を開始し、ループを終了して0を出力します。これはもちろん望ましくありません。
上記のシナリオは可能ですか?または、スレッドコンテキストの切り替え中に物理メモリがコミットされるという保証はありますか?
このウィキによると、
プログラムがシングルCPUマシンで実行される場合、ハードウェアは必要な簿記を実行して、すべてのメモリ操作がプログラマーによって指定された順序(プログラム順序)で実行されたかのようにプログラムが実行されるようにします。したがって、メモリバリアは必要ありません。
ユニプロセッサマルチスレッドアプリケーションについては明示的に言及されていませんが、このケースが含まれています。
それが正しい/完全かどうかはわかりません。これはハードウェア(弱い/強いメモリモデル)に大きく依存する可能性があることに注意してください。したがって、回答に知っているハードウェアを含めることをお勧めします。ありがとう。
PS。ここでは、デバイスのI/Oなどは私の関心事ではありません。そして、それはシングルコアユニプロセッサです。
編集:リマインダーをくれたNitsanに感謝します。ここではコンパイラの並べ替えはなく(ハードウェアの並べ替えのみ)、スレッド2のループは最適化されていないと想定しています。繰り返しになりますが、悪魔は詳細にあります。
concurrency - 一貫した順序で見られる同時ストア
インテル アーキテクチャ ソフトウェア開発者マニュアル、 2012年 8 月、vol. 3A、セクション。8.2.2:
2 つのストアは、ストアを実行するプロセッサ以外のプロセッサによって一貫した順序で表示されます。
しかし、これはそうでしょうか?
私が尋ねる理由は次のとおりです。HyperThreading を備えたデュアルコア Intel i7 プロセッサを検討してください。マニュアルのvol 。図 1、図 2-8 では、i7 の論理プロセッサ 0 と 1 は L1/L2 キャッシュを共有していますが、その論理プロセッサ 2 と 3 は別の L1/L2 キャッシュを共有しています。一方、すべての論理プロセッサは単一の L3 キャッシュを共有しています。論理プロセッサ 0 と 2 (L1/L2 キャッシュを共有していない) がほぼ同時に同じメモリ位置に書き込み、書き込みが現時点では L2 よりも深くないと仮定します。論理プロセッサ 1 と 3 (「ストアを実行するプロセッサ以外のプロセッサ」) は、「矛盾した順序で 2 つのストア」を認識できませんでしたか?
一貫性を保つために、論理プロセッサ 0 と 2 は SFENCE 命令を発行し、論理プロセッサ 1 と 3 は LFENCE 命令を発行してはいけませんか? それにもかかわらず、マニュアルはそうではないと考えているようであり、この問題に関するその意見は単なる誤植のようには見えません. わざとらしい。よくわかりません。
アップデート
@Benoit の回答に照らして、次の質問: したがって、L1 と L2 の唯一の目的は、負荷を高速化することです。ストアを高速化するのは L3 です。そうですか?