問題タブ [numa]

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 に答える
295 参照

numa - リモート メモリ アクセスの割合を測定する

私は 2 つのノードを持つ NUMA マシンで作業しています。コードをプロファイリングして、リモート メモリへのメモリ アクセスの割合を測定しようとしています。

私のマシンは AMD Interlagos (Family 15h) です。Perf のサポートは Linux 3.9 で導入されましたが、3.8 以降のカーネル バージョンへのアップグレードに問題があったため、現時点では代替手段を検討しています。

PAPI を見てみましたが、 Native Event の使い方がわかりませんでした

0 投票する
0 に答える
454 参照

java - Java プロセスが、使用可能なプロセッサーの「正しくない」数を報告する

以下を使用して、8 ノードの NUMA マシンで Java 1.6 プロセスを実行しています。

によって報告されているように、各ノードには 8 つの CPU がありますnumactl --hardware

関数呼び出しは をRuntime.getRuntime().availableProcessors()返します64

制限Runtimeがあるにもかかわらず、プロセスのオブジェクトが 64 の使用可能なプロセッサを報告するのはなぜですか? cpunodebindJava プロセスで使用できる実際のプロセッサ数を取得する方法はありますか?

0 投票する
7 に答える
15429 参照

c++ - Linux での memcpy のパフォーマンスの低下

最近、いくつかの新しいサーバーを購入しましたが、memcpy のパフォーマンスが低下しています。memcpy のパフォーマンスは、ラップトップと比較してサーバーで 3 倍遅くなります。

サーバー仕様

  • シャーシとモボ:SUPER MICRO 1027GR-TRF
  • CPU: 2x Intel Xeon E5-2680 @ 2.70 Ghz
  • メモリ: 8x 16GB DDR3 1600MHz

編集:わずかに高い仕様の別のサーバーでもテストしており、上記のサーバーと同じ結果が表示されます

サーバー 2 の仕様

  • シャーシとモボ: SUPER MICRO 10227GR-TRFT
  • CPU: 2x Intel Xeon E5-2650 v2 @ 2.6 Ghz
  • メモリ: 8x 16GB DDR3 1866MHz

ラップトップの仕様

  • シャーシ: レノボ W530
  • CPU: 1x インテル Core i7 i7-3720QM @ 2.6Ghz
  • メモリ: 4x 4GB DDR3 1600MHz

オペレーティング·システム

コンパイラ (すべてのシステム)

@stefan からの提案に基づいて、gcc 4.8.2 でもテストされています。コンパイラ間のパフォーマンスの違いはありませんでした。

テスト コード 以下のテスト コードは、製品コードで発生している問題を再現するための定型テストです。このベンチマークが単純であることは承知していますが、問題を悪用して特定することができました。このコードは、2 つの 1GB バッファーとそれらの間に memcpy を作成し、memcpy 呼び出しのタイミングを計ります。コマンド ラインで別のバッファ サイズを指定するには、./big_memcpy_test [SIZE_BYTES] を使用します。

ビルドする CMake ファイル

試験結果

ご覧のとおり、サーバーの memcpy と memset は、ラップトップの memcpy と memset よりもはるかに低速です。

さまざまなバッファ サイズ

100MB から 5GB までのバッファを試しましたが、すべて同様の結果でした (サーバーはラップトップより遅い)。

NUMA アフィニティ

NUMA でパフォーマンスの問題を抱えている人について読んだので、numactl を使用して CPU とメモリのアフィニティを設定しようとしましたが、結果は同じままでした。

サーバー NUMA ハードウェア

ラップトップ NUMA ハードウェア

NUMA アフィニティの設定

これを解決する助けがあれば大歓迎です。

編集:GCCオプション

コメントに基づいて、さまざまな GCC オプションでコンパイルを試みました。

-march と -mtune をネイティブに設定してコンパイルする

結果: まったく同じパフォーマンス (改善なし)

-O3 の代わりに -O2 を使用してコンパイルする

結果: まったく同じパフォーマンス (改善なし)

編集: NULL ページを回避するために、0 ではなく 0xF を書き込むように memset を変更しました (@SteveCox)

0 以外の値で memsetting しても改善はありません (この場合は 0xF を使用)。

編集:キャッシュベンチの結果

私のテスト プログラムが単純すぎることを除外するために、実際のベンチマーク プログラム LLCacheBench ( http://icl.cs.utk.edu/projects/llcbench/cachebench.html )をダウンロードしました。

アーキテクチャの問題を回避するために、各マシンで個別にベンチマークを構築しました。以下は私の結果です。

ラップトップとサーバーの memcpy のパフォーマンス

非常に大きな違いは、大きなバッファ サイズでのパフォーマンスにあることに注意してください。テストされた最後のサイズ (16777216) は、ラップトップで 18849.29 MB/秒、サーバーで 6710.40 で実行されました。これは、パフォーマンスの約 3 倍の違いです。また、サーバーのパフォーマンス低下がラップトップよりもはるかに急勾配であることもわかります。

編集: memmove() は、サーバー上の memcpy() よりも 2 倍高速です

いくつかの実験に基づいて、テスト ケースで memcpy() の代わりに memmove() を使用してみましたが、サーバーで 2 倍の改善が見られました。ラップトップ上の Memmove() は memcpy() よりも遅く実行されますが、奇妙なことに、サーバー上の memmove() と同じ速度で十分に実行されます。なぜ memcpy はこんなに遅いのでしょうか?

memcpy とともに memmove をテストするようにコードを更新しました。memmove() を関数内にラップする必要がありました。インラインのままにしておくと、GCC が最適化し、me​​mcpy() とまったく同じように実行したためです (場所が重複していないことを知っていたため、gcc が memcpy に最適化したと仮定します)。

更新された結果

編集:素朴なMemcpy

@Salgar からの提案に基づいて、私は自分の素朴な memcpy 関数を実装してテストしました。

Naive Memcpy ソース

memcpy() と比較した単純な Memcpy の結果

編集:アセンブリ出力

シンプルな memcpy ソース

アセンブリ出力: これは、サーバーとラップトップの両方でまったく同じです。スペースを節約し、両方を貼り付けません。

進捗!!!!asmlib

@tbenson からの提案に基づいて、asmlibバージョンの memcpy で実行してみました。私の結果は最初は貧弱でしたが、SetMemcpyCacheLimit() を 1GB (バッファーのサイズ) に変更した後、単純な for ループと同等の速度で実行されました!

悪いニュースは、memmove の asmlib バージョンが glibc バージョンより遅いことです。現在、300ms マークで実行されています (memcpy の glibc バージョンと同等)。奇妙なことは、ラップトップで SetMemcpyCacheLimit() を多数にするとパフォーマンスが低下することです...

以下の結果では、SetCache でマークされた行に SetMemcpyCacheLimit が 1073741824 に設定されています。

asmlib の関数を使用した結果:

キャッシュの問題に傾倒し始めていますが、これは何が原因でしょうか?

0 投票する
0 に答える
1018 参照

caching - キャッシュ コヒーレンシの問題は、UMA アーキテクチャにも適用されますか?

共有メモリ コンピュータ アーキテクチャは、特定のメモリ位置へのアクセス時間がすべてのプロセッサで同じかどうかによって、Uniform Memory Access (UMA) と Non-Uniform Memory Access (NUMA) に分けられることを学びました。また、NUMA アーキテクチャは、変更されたデータをあるプロセッサ (またはコア) のキャッシュから別のプロセッサのキャッシュに伝播 (または無効化) するメカニズムを備えているかどうかに基づいて、キャッシュ コヒーレントと非キャッシュ コヒーレントにさらに分類できることも学びました。 「ccNUMA」という用語に。(間違っていたら訂正お願いします...)

この質問に基づいて、NUMA という用語は特にキャッシュではなくメイン メモリへのアクセス時間を指していることも理解しています。そのため、ほとんどのマルチプロセッサ システムは必然的に分散キャッシュを持っていますが、これらのシステムは、均一にアクセスできる場合でも UMA と呼ばれます。メインメモリ。

私が理解できないのは、「ccUMA」アーキテクチャの概念がめったに言及されないのはなぜですか? たとえば、ウィキペディアにはccNUMA (NUMA にリダイレクトする) のページしかなく、ccUMA のページはなく、キャッシュ コヒーレンスのページはどちらにも明示的に言及していません (ただし、Distributed Shared Memoryにリンクしていることを除いて、ほぼ同等のようです)。 NUMA に...) また、ccUMA の Google 検索では、ccNUMA よりもはるかに少ない結果が返されます...

キャッシュの一貫性の問題は、UMA アーキテクチャには適用されませんか? あるように思えますが、なぜ言及されていないのですか?

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

c++ - 特定の NUMA メモリ ノードで C++ オブジェクトをインスタンス化する方法は?

シンプルな C コードは、libnumaライブラリを使用して、NUMA システムの特定のメモリ ノードにメモリを割り当てることができます。たとえば、次の関数を使用して実行できます。

メモリノードでクラスをインスタンス化するにはどうすればよいですか? 私が考えることができる1つの方法は次のとおりです。

これは機能しますか?

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

performance - ソフトウェア キャッシュは NUMA マシンのパフォーマンスを改善する必要がありますか?

NUMA マシンにはローカル キャッシュがないため、ソフトウェア キャッシュを実装すると、リモート メモリへのアクセスが必要なタスクのパフォーマンスが向上しますか?

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

linux - 実際の pte とは (NUMA の移行 pte とは対照的に)

Linux で NUMA のドキュメントを読んでソース コードを調べていると、タイプがSWP_MIGRATION_WRITEorの PTE である移行エントリSWP_MIGRATION_READが通常の PTE に置き換えられていることがわかります。さて、ノーマルPTEとは何ですか?どのような情報を含める必要がありますか?

0 投票する
0 に答える
79 参照

linux - ページを書き込むための NUMA コードと残りの Linux スワップの間のリンクはどこにありますか

そのため、Linux の通常のページでtry_to_unmapは、特定のページのスワップ エントリを作成し、pageoutそれを呼び出してスワップ スペースへの書き込みを処理mapping->a_ops->writepageします。さて、shrink_page_listピースをつなぎ合わせます。

一方、NUMA ページのtry_to_unmap場合、特定のページの NUMA 移行エントリが作成されますが、コード内のどこに実際に書き出され、コード内のどこに接着されているのかわかりません。

リンク知ってる人いますか?

ありがとう。

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

java - NUMA アーキテクチャの効率的な使用

CPU とメモリを集中的に使用するマルチスレッド Java プログラムを作成しています。プログラムの目標は、グラフに対して何らかのアルゴリズムを実行することです。このプログラムは、Linux を実行している NUMA マシンで実行されますが、可能な限り最高のパフォーマンスを得たいと考えています。

このために、各 NUMA ノードごとに多数のグラフのコピーを作成して、各スレッドがローカル メモリ上のグラフにアクセスできるようにします。

ローカル メモリ割り当ての一部は、グラフの新しい各コピーを割り当てる前にアフィニティを設定することによって既に行われています。これは jna で行われるため、可能であれば、このライブラリを使用し、jni コードを追加しないことを好みます。

私の質問は、ローカル メモリから読み取りを行うために、どのコアでワーカー スレッドが実行されているかを確認する方法です。

実行中にスレッドとコアのバインディングが変更される可能性があることを理解しています。ただし、カーネルはすべてのタイム スライスで同じ NUMA ノードでスレッドを実行しようとします。したがって、ほとんどの場合、スレッドが実行されているコアを最初に確認するだけで機能します。