問題タブ [false-sharing]
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++ - データがopenmpで読み取られると、偽の共有が発生しますか?
OpenMP 並列化を使用する C++ プログラムを使用している場合、異なるスレッドがデータを読み取るためだけに小さな共有配列を常に使用する場合、この場合、偽共有は発生しますか? つまり、メモリ書き込み操作のみに関連する偽共有であるか、メモリ読み取り操作でも発生する可能性があります。
c++ - 複数のスレッドから同じキャッシュラインを使用しても深刻な速度低下が発生しないのはなぜですか?
このスニペットを見てください:
この小さなプログラムは、4 つの異なるスレッドから、隣接する 4 つのバイトを何度もインクリメントします。以前は、ルールを使用していました。異なるスレッドから同じキャッシュ ラインを使用しないでください。キャッシュ ラインの共有は良くないからです。N=4
したがって、4 スレッド バージョン ( ) は 1 スレッド バージョン ( ) よりもはるかに遅いと予想しましたN=1
。
ただし、これらは私の測定値です(Haswell CPUで):
- N=1: 1 秒
- N=4: 1.2秒
だからN=4
それほど遅くはありません。*1
別のキャッシュ ラインを使用すると( に置き換えます*64
)、N=4
少し速くなります: 1.1 秒。
アトミック アクセス (のコメントを入れ替えるtypedef
) の同じ測定値、同じキャッシュ ライン:
- N=1: 3.1 秒
- N=4: 48 秒
したがって、N=4
ケースははるかに遅くなります(予想どおり)。異なるキャッシュ ラインを使用すると、3.3 秒N=4
と同様のパフォーマンスが得られます。N=1
これらの結果の背後にある理由がわかりません。N=4
非アトミックなケースで深刻な速度低下が発生しないのはなぜですか? 4 つのコアはキャッシュに同じメモリを持っているので、何らかの方法で同期する必要がありますね。ほぼ完全に並行して実行するにはどうすればよいでしょうか? アトミックなケースだけで深刻な減速が発生するのはなぜですか?
この場合、メモリがどのように更新されるかを理解する必要があると思います。buffer
最初は、キャッシュにコアはありません。1回のfor
反復の後 ( fn
)、4 つのコアすべてbuffer
がキャッシュ ラインを保持していますが、各コアは異なるバイトを書き込みます。これらのキャッシュラインはどのように同期されますか (アトミックでない場合)? キャッシュは、どのバイトがダーティかをどのように認識しますか? または、このケースを処理する他のメカニズムはありますか? なぜこのメカニズムはアトミックメカニズムよりもはるかに安価なのですか (実際にはほとんど無料です)?
c++ - この std::vector push_back が OpenMP 並列領域で発生すると、誤った共有が発生しますか?
以下のサンプル コードは、作業コードの簡易版です。std::vector::push_back
このコードでは、共有変数への書き込みは、が呼び出される最後の行でのみ行われます。
この操作が誤った共有につながるのではないかと思ってpush_back
いたので、それを取り除くことでさらに最適化する機会が得られました. この問題を掘り下げる前に、まずいくつかのベンチ テストを行うことにしました。
ではchrono
、ウォール クロックの実行時間some_heavy_work()
とクリティカル セクションを別々に測定しました。後者は前者の約10^(-4)倍の実行時間を要したので、false-sharing の有無にかかわらず、この部分を最適化してもほとんどメリットがないと判断しました。
とにかく、ここで偽の共有が問題になるかどうか、私はまだ興味があります. の内部実装を見る必要がありstd::vector
ますか? どんな啓発も大歓迎です。(私はVS2015を使用しています)
c - OpenMP - 偽共有なしの配列挿入
プログラムを並列化するために C で OpenMP を使用しています。私のプログラムには、計算された値を配列に挿入するセクションがあります。コードは次のようになります。
私が学んだことから、このコードは配列でFalse Sharingの問題が発生すると思いますarr
。この問題を回避するために、次のようないくつかの方法を見つけました。
- 配列パディング
- チャンクによるスケジューリング
これら 2 つの方法では、プロセッサのキャッシュ サイズがどれくらい大きいかを知る必要があります。未知のシステムでプログラムを実行したいとします (キャッシュ サイズがどのくらいかわかりません)。キャッシュ サイズを知る必要のないこのコードの回避策はありますか? それとも、プログラムが実行されているシステムのキャッシュ サイズを読み取ることができる C コードでしょうか?