2

クラスターの 1 つのノードでSTREAM ベンチマークのMPI バージョンを実行して、さまざまな数の MPI プロセスの持続可能な帯域幅を測定したいと考えています。各ノードは、2 つのインテル® Xeon® プロセッサー E5-2680 v3 (12 コア) で構成されています。

以下では、openmpi v. 1.8.2 とオプションmap-by core. ソースはラッパーを使用してコンパイルされました

icc (ICC) 15.0.0 20140723

コンパイラ オプションを使用して

-O3 -xHost.

各コアは長さ 2*10^6 の倍精度配列を使用しており、テストは 50 回繰り返されます。

01: Triad: 22017.3438
02: Triad: 29757.8394
03: Triad: 30224.1759
04: Triad: 30080.7369
05: Triad: 30209.6233
06: Triad: 30028.2044
07: Triad: 35064.7215
09: Triad: 44961.7710
10: Triad: 49721.1975
11: Triad: 54814.0579
12: Triad: 58962.7279
13: Triad: 64405.3634
14: Triad: 69330.3864
15: Triad: 74137.0623
16: Triad: 78838.8075
17: Triad: 84006.1067
18: Triad: 89012.6674
19: Triad: 94105.8690
20: Triad: 98744.3634
21: Triad: 103948.1538
22: Triad: 108055.3862
23: Triad: 114154.4542
24: Triad: 118730.5429

私が困惑しているのは、2 ~ 6 プロセスの測定された持続可能な帯域幅の停滞です。使用されているプロセッサのターボ ブーストが結果に偏りを与えている可能性があると思います。どうやらTurbo Boostはいくつかのコアが使用されている場合にのみアクティブになりますが、結果を正しく解釈する方法がわかりません.

Turbo Boost を「オフ」にするには、次のように STREAM ベンチマークを変更することが考えられます。

  • 使用可能な 24 個のコアすべてを常に使用して、ベンチマーク全体でプロセッサの負荷をほぼ一定に維持します
  • ベンチマークの MPI コミュニケーターMPI_COMM_WORLDを 2 つの別々のものに分割します。1 つのコミュニケーターは、実際にベンチマークを実行するN 個のプロセスのグループに関連付けられます。もう 1 つのグループには、残りの24-N 個のプロセスが含まれます。これらのプロセスは、コアをビジー状態に保ち、ターボ ブーストを防止することのみを目的としています。
  • 24-Nプロセスは、L1 キャッシュからのデータのみを使用して、他のプロセスへの影響を最小限に抑えます。
  • ベンチマークの実行時間を数分に延長します (ターボ ブーストの効果は数秒以上持続しませんか?)

最初の実装では、L1 キャッシュ (32kByte) に収まる必要があるデータ セットの残りの24-Nプロセスにトライアド カーネルのみを使用します。ベンチマークの繰り返し回数は 5000 に引き上げられ、データ配列の長さのサイズは 1*10^7 に引き上げられました。この関数fooは、ループのアンロールを防止するために (成功したか?) 呼び出されます。先行する if 条件はfalse、プログラムの実行全体を通じて行われます。関連するコードは次のとおりです

  if (rank < N) {
    ...
    UNMODIFIED BENCHMARK
    ...
  } else {
    scalar=3.0;
    for (i=0; i<10000000000; i++) {
      for (j=0; j<1000; j++) a[j] = b[j]+scalar*c[j];
      if (a[2] < 1.0) foo(a,b,c);
    }   
  }

a、b、および c はstatic double a[LEN],b[LEN],c[LEN]、main の外部として宣言されています。また、 static 修飾子とそのベンチマークへの影響に関するこの議論も読みました。通話fooが本当に必要かどうかはわかりません。

残念ながら、私のアプローチでは、ベンチマークとは異なる結果にはなりませんでした。

私のアプローチの何が問題になっていますか?代替手段について知っていますか、またはベンチマークをどのように変更する必要があるかについての提案はありますか?


編集:

あるユーザーが私がベンチマークに使用したコードに興味を示したので:

PETSc に付属する STREAM ベンチマークの修正版を使用しました。

http://www.mcs.anl.gov/petsc/

システムに PETSc をインストールすると、次の場所にベンチマークが表示されます。src/benchmarks/streams

ソースコードのみに興味がある場合は、GitHub ページで最新バージョンを見つけることができます。

https://github.com/petsc/petsc/tree/master/src/benchmarks/streams

4

1 に答える 1

1

プログラムに使用されるCPUサイクルの実際のカウントを取得するためにハードウェアパフォーマンス監視ユニットにアクセスできるプロファイリングツールを使用して、現在のCPUクロックを外部で測定できます。たとえば、Linuxperfperf statモード (またはperf stat -e cpu-clock,cyclesシステム全体) でこれを行います。イベント カウントとまたはのような壁時間イベントの両方がある場合perf stat -a -A、平均 CPU 周波数を出力します。cyclescyclestask-clockcpu-clock

ウォール タイム (gettimeofday) とサイクル パフォーマンス カウンターを読み取ることで、これを内部的に計算してプログラムすることができます (ただし、ほとんどの TSC は現在Invariantであるため、RDTSC ではありません。「不変 TSC は CPUID.80000007H:EDX[8] で示されます」)。平均頻度 = 消費サイクル数 / 消費時間。テスト関数の直前と直後、またはすべてのテスト関数 (コピー/スケール/ADD ストリーム テストが有効な場合) の前後で実行して、より詳細な周波数プロファイルを取得できます (HPC トレース プロジェクトがあり、すべての時間とサイクルを記録できます)。 MPI 呼び出し)。

CPU サイクルの内部読み取り (プログラム フラグメントの平均周波数を計算するため) は、perf_events (Linux、これは で使用されますperf)、perfmon、libpfm3/libpfm4、PAPI、または HPC の一部で使用されるその他の PMU アクセスライブラリなどの PMU API で実行できます。世界。一部の PMU API は、OS と CPU アーキテクチャ間で移植可能です。

または、Boost を無効にする ( https://stackoverflow.com/a/38034503/196561 ) か、非常に冷たい水で水冷を使用して永続的に有効にする (15 コア以上の Xeon では動作しない可能性があります)。

于 2016-06-26T01:54:13.767 に答える