*並列実行プログラムの最適化 [#lc0ec8aa]
#contents

旧システムからのプログラムの移行についてまとめましたので、[[「旧システムからのプログラムの移行」>旧システムからのプログラムの移行#j40218a9]]を参照下さい。

** 自動並列化 [#a8f1a4a1]
parallelオプションの指定により、コンパイラがソースコード内の全ループに対して、並列化が可能か否かの解析を行います。~
~
- -parallel
--ソースファイル内の全てのループを解析し、安全に並列化できるループがあれば並列バイナリを生成します。
- -par-threshold[n]
-- 自動並列化の性能向上の見込みのしきい値(確信度)を設定します。([n]は0~100まで) デフォルトは100。
-- n が 0 のとき、ループは、計算量にかかわらず、並列化可能ならば常に自動並列化されます。
n が 100 のとき、並列化が可能でかつ並列化による性能向上が見込まれる場合のみ自動並列化されます。
- -qopt-report[=n] -qopt-report-phase=par (-qopt-reportは省略可)
- -qopt-report[=n] -qopt-report-phase=par (-qopt-report[=n]は省略可)
~
自動並列化の診断情報を出力します。
--n=1:並列化されたループを出力します。
--n=2:レベル 1 の詳細に加えて、並列化されなかったループとその簡単な理由を出力します。
--n=3:レベル 2 の詳細に加えて、private、shared、reduction として分類されているメモリー位置を出力します。
--n=2:レベル1の詳細に加えて、並列化されなかったループとその簡単な理由を出力します。
--n=3:レベル2の詳細に加えて、private、shared、reduction として分類されているメモリー位置を出力します。
--n=4:レベル3と同じ
--n=5:レベル 4 の詳細に加えて、並列化を妨げている依存関係を出力します。
--n=5:レベル4の詳細に加えて、並列化を妨げている依存関係を出力します。
--デフォルトはn=2。
~
(*)コンパイラのバージョン15以降、診断情報を出力する -opt-reportオプションが -qopt-reportに変わりました。また、-par-reportオプションが-qopt-report-phase=parに変わりました。-opt-report、-par-reportもお使い頂けますがワーニングメッセージが出力されます。
~
(*)診断情報は、標準出力ではなく「バイナリ名.optrpt」ファイルに出力されます。
~
-例)~
 $ cat mxm.f
 
   1       SUBROUTINEMXM(A,B,C,L,M,N,N1)
   2       DIMENSION A(M,L),B(N1,M),C(N1,L)
   3       DO  K =1,L
   4         DO  I =1,N
   5           C(I,K)=0.
   6         ENDDO
   7       ENDDO
   8       DO K =1,L
   9         DO I =1,N
  10           DO J =1,M
  11             C(I,K)=C(I,K)+B(I,J)*A(J,K)
  12           ENDDO
  13         ENDDO
  14       ENDDO
  15       RETURN
  16       END
 
 $ ifort  -c  -O3  -xAVX -parallel  -qopt-report -qopt-report-phase=par mxm.f
 ifort: remark #10397: optimization reports are generated in *.optrpt files in the output location
 
 mxm.optrptファイルに診断情報が出力されます。
 8行目のループが並列化されたことがわかります。
 
 $ ifort  -c  -O3  -xAVX  -parallel  -par-threshold0 -qopt-report -qopt-report-phase=par  mxm.f
 ifort: remark #10397: optimization reports are generated in *.optrpt files in the output location
 
 mxm.optrptファイルに診断情報が出力されます。
 3行目と8行目のループが並列化されたことがわかります。

- -par-threshold100(デフォルト)の場合は、初期化ループ(3行目)には充分な処理量が無く、性能向上が確実ではないと判断し、並列化しません。
- -par-threshold0の場合は、性能向上の見込み値には関係なく、安全に並列化できるループは全て並列化します。
** OpenMP [#bff9624d]
qopenmpオプションの指定により、ソースコード内のOpenMP指示行を有効にします。
~
(*)コンパイラのバージョン15以降、OpenMP指示行を有効にするオプションが -openmp から -qopenmp へ変わりました。-openmp もお使い頂けます。
~
(*)診断情報は、「バイナリ名.optrpt」ファイルに出力されます。

- -qopenmp
--OpenMP指示行を有効にします。
- -qopt-report[=n] -qopt-report-phase=openmp (-qopt-reportは省略可)
- -qopt-report[=n] -qopt-report-phase=openmp (-qopt-report[=n]は省略可)
--OpenMP並列化の診断情報を出力します。
--n=1:正常に並列化されたループ、領域、セクション、タスクを出力します。
--n=2:1の情報に加えて、正常に処理された MASTER 構造、SINGLE 構造、CRITICAL 構造、ORDERED 構造、ATOMIC 宣言子などを示す診断メッセージを出力します。
--デフォルトはn=2。
~
(*)コンパイラのバージョン15以降、診断情報を出力する -opt-reportオプションが -qopt-reportに変わりました。また、-openmp-reportオプションが-qopt-report-phase=openmp に変わりました。-opt-report、-openmp-reportもお使い頂けますがワーニングメッセージが出力されます。
-例)~
 $ cat mxm2.f
 
   1       SUBROUTINE MXM (A,B,C,L,M,N,N1)
   2       DIMENSION A(M,L),B(N1,M),C(N1,L)
   3 !$OMP PARALLEL DO
   4       DO  K =1,L
   5         DO  I =1,N
   6           C(I,K)=0.
   7         ENDDO
   8       ENDDO
   9 !$OMP PARALLAL DO
  10       DO K =1,L
  11         DO I =1,N
  12           DO J =1,M
  13             C(I,K)=C(I,K)+B(I,J)*A(J,K)
  14           ENDDO
  15         ENDDO
  16       ENDDO
  17       RETURN
  18       END
 
 $ ifort -c  -O3 -xAVX  -qopenmp  -qopt-report -qopt-report-phase=openmp mxm2.f
 ifort: remark #10397: optimization reports are generated in *.optrpt files in the output location
 
 mxm2.optrptファイルに診断情報が出力されます。

- -qopenmpと-parallelを同時に指定したとき
(*) -parallelと-qopenmpを同時に指定したとき
~
コンパイラは全ループに対して並列化可能か否かの解析を行い、可能であれば並列化します。~
OpenMP指示行が指定されたループは、-qopenmpによって並列化さます。~
OpenMP指示行が指定されたループは、-qopenmpによって並列化さます。
-例)
 $ cat mxm3.f
 
   1       SUBROUTINE MXM (A,B,C,L,M,N,N1)
   2       DIMENSION A(M,L),B(N1,M),C(N1,L)
   3       DO  K =1,L
   4         DO  I =1,N
   5           C(I,K)=0.
   6         ENDDO
   7       ENDDO
   8 !$OMP PARALLEL DO
   9       DO K =1,L
  10         DO I =1,N
  11           DO J =1,M
  12             C(I,K)=C(I,K)+B(I,J)*A(J,K)
  13           ENDDO
  14         ENDDO
  15       ENDDO
  16       RETURN
  17       END
 
 $ ifort -c -O3 -xAVX -parallel  -par-threshold0  -qopt-report \
 -qopt-report-phase=par -qopenmp  -qopt-report-phase=openmp  mxm3.f
 ifort: remark #10397: optimization reports are generated in *.optrpt files in the output location
 
 mxm3.optrptファイルに診断情報が出力されます。
 
 3行目と9行目のループが自動並列化され、8行目のOpenMP指示行が有効になります。
 9行目のループは自動並列化とOpenMPの両方から並列化されますが、環境変数
 OMP_NESTED=falseが設定されているため、環境変数OMP_NUM_THREADSで指定した
 スレッド数で実行されます。OMP_NUM_THREADSについては
 [[「自動並列化/OpenMP並列化プログラムの実行」:#lafe8ab3]]を参照下さい。
-3行目と9行目のループが自動並列化され、8行目のOpenMP指示行が有効になります。
-9行目のループは自動並列化とOpenMPの両方から並列化されますが、環境変数OMP_NESTED=falseがデフォルトで設定されているため、環境変数OMP_NUM_THREADS
で指定したスレッド数で実行されます。
-OMP_NESTED=falseは入れ子になった並列処理を無効にします。

**自動並列化/OpenMP並列化プログラムの実行 [#lafe8ab3]
OMP_NUM_THREADSについては、[[「自動並列化/OpenMPプログラムの実行スレッド数」>#lafe8ab3]]を参照下さい。

**自動並列化/OpenMPによる並列プログラムのデータ分散~ [#ke6c26fe]
-EICシステムでは、「ファーストタッチ」を採用しています。データは、最初にそのデータにタッチ(書き込みまたは読み込み)したプロセスのローカルメモリに配置されるというものです。もし、配列(配列Aとする)を初期化しているループが並列化されていないと1CPU実行であるために、配列Aはある1つのノードに配置されます。配列Aを処理する並列実行領域では、複数のプロセッサが1つのノードへアクセスすることになります。このような状況ではプログラムの性能向上は望めません。可能なかぎり初期化ループも並列化してください。~
**自動並列化/OpenMPプログラムの実行スレッド数 [#lafe8ab3]
-環境変数OMP_NUM_THREADSに実行スレッド数を指定します。
 $ setenv OMP_NUM_THREADS 4
 
ジョブスクリプト、ジョブ投入方法については、[[「利用方法」>利用方法#w8339976]]を参照下さい。
 
**自動並列化/OpenMPによる並列プログラムのデータ分散 [#ke6c26fe]
-EICシステムでは、「ファーストタッチ」を採用しています。データは、最初にそのデータにタッチ(書き込みまたは読み込み)したプロセスのローカルメモリに配置されるというものです。もし、配列(配列Aとする)を初期化しているループが並列化されていないと1CPUコア実行であるために、配列Aはある1つのノードに配置されます。配列Aを処理する並列実行領域では、複数のプロセッサが1つのノードへアクセスすることになります。このような状況ではプログラムの性能向上は望めません。可能なかぎり初期化ループも並列化してください。
~
例)
    real*8 A(n), B(n), C(n), D(n)
 
     do i=1, n
         A(i) = 0.
         B(i) = i/2
         C(i) = i/3
         D(i) = i/7
     enddo
 !$omp parallel do
     do i=1, n
         A(i) = B(i) + C(i) + D(i)
     enddo
~
#ref(first_touch1.JPG,left,nowrap,80%)
~
     real*8 A(n), B(n), C(n), D(n)
 !$omp parallel do
     do i=1, n
         A(i) = 0.
         B(i) = i/2
         C(i) = i/3
         D(i) = i/7
     enddo
 !$omp parallel do
     do i=1, n
         A(i) = B(i) + C(i) + D(i)
     enddo
#ref(first_touch2.JPG,left,nowrap,80%)

** スレッドのスタックサイズ [#zd84c197]
-各ユーザが使用可能なスタックサイズの上限を6GBに設定しています(メモリ使用量の上限ではありません)。関数や手続きの中で宣言されるローカル変数がスタック領域にアロケーションされます。上限を越えてスタックに領域を確保しようとすると、AddressErrorまたは、SegmentationFaultでプログラムは終了します。この場合、データを静的にアロケーションするために、COMMONブロックでデータ(配列)を宣言して下さい。
-各ユーザが使用可能なスタックサイズの上限を4GBに設定しています(メモリ使用量の上限ではありません)。関数や手続きの中で宣言されるローカル変数がスタック領域にアロケーションされます。上限を越えてスタックに領域を確保しようとすると、AddressErrorまたは、SegmentationFaultでプログラムは終了します。この場合、データを静的にアロケーションするために、COMMONブロックでデータ(配列)を宣言して下さい。
-環境変数KMP_STACKSIZEには自動並列化/OpneMPプログラムのスレーブスレッドが使用できるスタック領域の最大容量を指定します。スレーブスレッドのプライベート変数が対象です。共有変数、マスタースレッドのプライベート変数は対象ではありません。デフォルトでは2GBが設定されています。
-単位として、k(キロバイト)、m(メガバイト)、g(ギガバイト)、t(テラバイト)が使えます。~
-単位として、k(キロバイト)、m(メガバイト)、g(ギガバイト)、t(テラバイト)が使えます。
-シリアル実行で実行できたプログラムが、自動並列化/OpenMP並列化したときにエラー終了してしまったというような場合にはスレッドのスタック領域が不足している可能性がありますので、KMP_STACKSIZEを増やしてください。
~
~
例)
 $export KMP_STACKSIZE=4g
 $setenv KMP_STACKSIZE 6g

**MPI [#t936c9e4]
コマンド行の末尾にMPIライブラリのリンクを指示してください。~
~
 
例)
 $ ifort  -O3  -xSSE4.2  ex_mpi.f -lmpi
 $ ifort  -O3  -xAVX  ex_mpi.f -lmpi
実行時にはmpiexec_mptコマンドを使ってジョブを起動してください。
~
ジョブスクリプト、ジョブ投入方法については、[[「利用方法」>利用方法#w8339976]]を参照下さい。

-MPIのデータ型~
FortranプログラムでのMPIのデータ型とそれに対応するFortranでのデータ型は以下の通りです。~
|~MPIのデータ型|~Fortranのデータ型|~bit|
|MPI_DATATYPE_NULL|対応する型はありません|―|
|MPI_INTEGER|INTEGER|32|
|MPI_REAL|REAL|32|
|MPI_DOUBLE_PRECISION|DOUBLE_PRECISION|64|
|MPI_COMPLEX|COMPLEX|64|
|MPI_DOUBLE_COMPLEX|DOUBLE_COMPLEX|128|
|MPI_LOGICAL|LOGICAL|4|
|MPI_CHARACTER|CHARACTER|1|
|MPI_INTEGER1|INTEGER(KIND=1)|8|
|MPI_INTEGER2|INTEGER(KIND=2)|16|
|MPI_INTEGER4|INTEGER(KIND=4)|32|
|MPI_INTEGER8|INTEGER(KIND=8)|64|
|MPI_REAL2|REAL(KIND=2)|16|
|MPI_REAL8|REAL(KIND=8)|64|
|MPI_REAL16|REAL(KIND=16)|128|
|MPI_BYTE|BYTE|1|
~
CプログラムでのMPIのデータ型とそれに対応するCでのデータの型は以下の通りです。~
|~MPIのデータ型|~Cのデータ型|~bit|
|MPI_CHAR|char|8|
|MPI_SHORT|short|16|
|MPI_INT|int|32|
|MPI_LONG|long|64|
|MPI_UNSIGHNED_CHAR|unsighned char|8|
|MPI_UNSIGHNED_SHORT|unsighned short|16|
|MPI_UNSIGHNED|unsighned int|32|
|MPI_UNSIGHNED_LONG	|unsighned long|64|
|MPI_FLOAT|float|32|
|MPI_DOUBLE|double|64|
|MPI_LONG_DOUBLE|long_double|128|
|MPI_BYTE|対応する型はありません|1|
|MPI_PACKED|対応する型はありません||
**ハイブリッド [#ka4a7d3a]
並列化を有効にするコンパイルオプションを指定して、リンク時にMPIライブラリをリンクします。~
~
例)
 $  ifort  -O3  -xSSE4.2 -openmp  -openmp-report1  hybrid.f  -lmpi
実行時にはmpiexec_mptコマンドを使ってジョブを起動してください。~
ジョブスクリプトの作成、ジョブの起動方法は、「[[バッチジョブ利用方法(基本)]]」、
「[[バッチジョブ(高速計算サーバ)]]」、「[[バッチジョブ(並列計算サーバ)]]」を参照ください。
**性能解析ツール [#m5de4d99]
-''実行時間のかかっている箇所を探す''~
 $  ifort  -O3  -xAVX -qopenmp  -qopt-report -qopt-report-phase=openmp hybrid.f  -lmpi
~
ジョブスクリプト、ジョブ投入方法は、[[「利用方法」>利用方法#w8339976]]」を参照ください。

**性能解析ツール [#m5de4d99]
-実行時間のかかっている箇所を探します

--自動並列化/OpenMPプログラム

---psrunコマンドにオプション -p を指定してください。 -p オプションの指定でマスタースレッドとスレーブスレッドの解析が可能です。
---psrunコマンドと共に自動並列化/OpenMPプログラムを実行すると、OMP_NUM_THREADSで指定した数のスレッドの他に1つの管理スレッドが起動されます。そのため解析結果ファイルも実行スレッド数+1個作られますが、管理スレッドの解析結果ファイルには情報はありません。
---再コンパイルは必要ありません。ただし、行毎の解析を行いたいときには、-gオプションを指定してコンパイルしてください。
~
psrunコマンドにオプション -p を指定してください。 -p オプションの指定で子スレッドまでの解析が可能です。psrunコマンドと共に自動並列化/OpenMPプログラムを実行すると、OMP_NUM_THREADSで指定した数のスレッドの他に1つの管理スレッドが起動されます。そのため解析結果ファイルも実行スレッド数+1個作られます。~
行毎の解析を行いたいときには、コンパイル時に -g オプションを指定してください。~
~
例)
 $ export  OMP_NUM_THREADS=4
 $ dplace  -x5  psrun  -p  ./a.out   <---dplaceコマンドのオプションは -x5 です。
 $ setenv OMP_NUM_THREADS 4
 $ dplace -x5 psrun -p ./a.out
~
実行終了後、解析結果ファイルがカレントディレクトリに作られます。
 $ ls*.xml
 a.out.3.4032.eich1.xml
 a.out.2.4032.eich1.xml
 a.out.4.4032.eich1.xml
 a.out.1.4032.eich1.xml
 a.out.0.4032.eich1.xml
(解析結果ファイル名はバイナリ名.スレッド番号.PID.ホスト名.xmlです。)~
psprocessコマンドで整形してください。~
~
解析結果ファイル名は「バイナリ名.スレッド番号.PID.ホスト名.xml」です。
~
psprocessコマンドで整形してください。
 
 $ psprocess  a.out.0.4032.eich1.xml
~
(*)解析結果ファイルを複数指定して、全スレッドの解析結果を表示するということはできません。~
 $ psprocess  a.out.0.4032.eich1.xml  a.out.2.4032.xml  a.out.3.4032.xml  <---不可
~
実行例)~
行毎の解析を行うために -g オプションを指定し、並列化のために自動並列化オプション指定します。
 $ ifort  -g  -O3 -xSSE4.2 -parallel  -par-threshold0  -par-report1  test.f
 $ dplace  -x5  psrun  -p  ./a.out
例)
~
行毎の解析を行うために -g オプションを指定し、並列化のために自動並列化オプションを指定してコンパイルします。
 $ ifort -g -O3 -xAVX -parallel -par-threshold0 -qopt-report -qopt-report-phase=par test.f
 $ dplace -x5 psrun -p ./a.out
 $ ls *.xml
 a.out.4.16904.eich1.xml
 a.out.3.16904.eich1.xml
 a.out.2.16904.eich1.xml
 a.out.1.16904.eich1.xml
 a.out.0.16904.eich1.xml
 $ psprocess  a.out.0.16904.eich1.xml
 
 ......
 Samples      Self%    Total%  Function  
      7922   87.82%   87.82%  L_jacobi__202__par_region0_2_137  
      1043   11.56%   99.38%  __intel_new_memcpy
          34     0.38%   99.76%  main$himenobmtxp_m_omp_$BLK
            6     0.07%   99.82%  _intel_fast_memcpy.J
        34    0.38%   99.76%  main$himenobmtxp_m_omp_$BLK
         6    0.07%   99.82%  _intel_fast_memcpy.J
 
 Samples     Self%  Total%   Function:File:Line
      1260  13.97% 13.97%   L_jacobi__202__par_:himeno_omp.f:215
      1162  12.88% 26.85%   L_jacobi__202__par_:himeno_omp.f:219
      1043  11.56% 38.41%   __intel_new_memcpy:??:0
       993   11.01% 49.42%   L_jacobi__202__par:himeno_omp.f:216
--MPIプログラム~
       993  11.01% 49.42%   L_jacobi__202__par:himeno_omp.f:216
 .......
--MPIプログラム
~
MPIプログラムを解析するときはpsrunコマンドに-fオプションを指定してください。
dplaceのオプションは、-s2となります。~
~
--ハイブリッドプログラム~
ハイブリッドプログラムを解析するときは、psrunコマンドに-fオプションと-pオプションを指定してください。~
実行時にはomplaceコマンドを指定して下さい。omplaceコマンドのオプションは、psrunを指定しないときと変わりません。
-''MFLOPS値を測る''~
--Xeon7500番台は浮動小数点演算にSSE命令を採用しています。SSE命令は4つの単精度演算、または2つ倍精度演算を1命令で行います。従って、カウントされる演算数は実際の演算数よりも少なくなります。より正確な浮動少数点演算数をカウントしたいときには、コンパイル時にSSE命令を無効にする-no-vecオプションを指定してください。(-xSSE4.2が指定されていなくても-no-vecオプションが必要です)~
-- -xSSE4.2と-no-vecが同時に指定されたときには、-no-vecが優先されます。~
-- -no-vecオプションは実行性能が落ちる場合がありますので、性能解析が終わりましたら、指定をはずしてください~
--ハイブリッドプログラム
~
--OpenMP/自動並列化プログラム~
環境変数PS_HWPC_CONFIGに以下のように設定してください。~
psrunコマンドに-pオプションを指定ください。~
 $ export PS_HWPC_CONFIG=${PS_DIR}papi3_mflops.xml
 $ export OMP_NUM_THREADS=4
 $ dplace -x5 psrun  -p  ./a.out <--dplace のオプションは -x5 です。
実行終了後、解析結果ファイルがカレントディレクトリに作られます。~
 $ ls*.xml
 a.out.3.2956.eich1.xml
 a.out.2.2954.eich1.xml
 a.out.4.2954.eich1.xml
 a.out.1.2954.eich1.xml
a.out.0.2954.eich1.xml
(注)並列数+1個の解析結果ファイルが作られます。1つは管理スレッドを解析した結果です。管理スレッドは仕事をしないので解析結果の数値はほぼゼロとなります。~
 $psprocessa.out.0.2954.eich1.xml
解析結果ファイルの内容が表示されます。~
解析結果の例)~
 IndexDescription  Counter Value
 ===============================================
     1Floatingpointoperations...  64695240024
     2Totalcycles...................146421545771
 
 EventIndex
 ===============================================
     1:PAPI_FP_OPS        2:PAPI_TOT_CYC
 
 Statistics
 ===============================================
 Countingdomain........................user
 Multiplexed...............................no
 Floatingpointoperationspercycle....0.442
 MFLOPS(cycles)...................1178.442
  <---MFLOPS値
 MFLOPS(wallclock)................1146.432  
 <---MFLOPS値
 CPUtime(seconds)...................54.899
 Wallclocktime(seconds).............56.432
 %CPUutilization......................97.284
~
(*)全スレッドの統計値を表示するには~
psprocessコマンドの-cオプションを使って、解析結果ファイルを1つのファイルにまとめます。そして、まとめたファイルをpsprocessコマンドで整形します。~
(統計を求める際には、管理スレッドの解析結果ファイルは対象からはずして下さい。)~
 $psprocess  -c  a.out.*.xml  > kekka.xml <--ファイル名は任意
 $ psprocess kekka.xml
 
 Minimum and Maximum                            Min          Max
 ====================================================
 % CPU utilization.......................   12.88 [eic]     20.02 [eic]
 CPU time (seconds)....................    0.05 [eic]       0.08 [eic]
 Floating point operations per cycle..     0.42 [eic]      0.61 [eic]
 MFLOPS (cycles)....................... 1111.68 [eic] 1625.49 [eic]
 MFLOPS (wall clock)...................  143.14 [eic]   263.23 [eic]
 Wall clock time (seconds).............     0.32 [eic]      0.59 [eic]
 
 Aggregate Statistics                         Median    Mean  StdDev     Sum
 ============================================================
 % CPU utilization........................    14.86    15.61      2.43   93.65
 CPU time (seconds).....................     0.06      0.06      0.01     0.36
 Floating point operations per cycle...      0.55      0.53      0.07     3.19
 MFLOPS (cycles)........................ 1457.24 1416.35  186.27 8498.11
 MFLOPS (wall clock)....................   227.60  221.04    40.62 1326.23
 Wall clock time (seconds)..............      0.37      0.39      0.10     2.36
ハイブリッドプログラムを解析するときは、psrunコマンドに-fオプションと-pオプションを指定してください。

--MPIプログラム~
~
環境変数PS_HWPC_CONFIGに以下を設定してください。~
psrunコマンドに-fオプションを指定してください。~
dplaceのオプションは-s2となります。~
 $export  PS_HWPC_CONFIG=${PS_DIR}/papi3_mflops.xml
 $mpiexec_mpt  -np 4 dplace -s2 psrun  -f  ./a.out
実行終了後、解析結果ファイルがカレントディレクトリに作られます。~
psprocessコマンドで整形してください。~
(*)全プロセスの統計値を表示するにはOpenMP/自動並列化の項目を参照下さい。~

--ハイブリッドプログラム~
-MPInside(MPIの通信時間を測る)
~
環境変数PS_HWPC_CONFIGに以下を設定してください。~
psrunコマンドに-f-pオプションを指定してください。~
 $ export   PS_HWPC_CONFIG=${PS_DIR}/papi3_mflops.xml
 $ export  OMP_NUM_THREADS=4
 $ mpiexec_mpt  -np 4  omplace(オプション) psrun  -f  -p  ./a.out
実行終了後、解析結果ファイルがカレントディレクトリに作られます。~
psprocessコマンドで整形してください。~
(*)全プロセス/スレッドの統計値を表示するにはOpenMP/自動並列化の項目を参照下さい。~
MPInsideを使ってMPIルーチンの通信時間を知ることができます。
~
-''perfcatcher(MPIの通信量を測る)''~
コマンド名はMPInsideです。
~
perfcatcherを使ってMPI関数の実行回数や、通信時間を知ることができます。~
コマンド名はperfcatchです。dplaceのオプションは-s1のままです。~
例)~
 $ mpiexec_mpt -np 4 dplace -s1perfcatch a.out
実行が終わるとカレントディレクトリに "MPI_PROFILING_STATS"というファイルが作成されます。ランク毎、MPI関数毎の通信時間がわかります。~
 Activity on process rank 0
~
例)
 $ mpiexec_mpt -np 4 dplace -s1 MPInside a.out
~
実行が終わるとカレントディレクトリに "mpinside_stats"というファイルが作成されます。
~
 .....
 >>>> Elapse times in (s) 0 1<<<<
 CPU   Comput   init     waitall  isend    irecv    barrier  bcast    allreduce
 0000 42.8395   0.0001   0.8088   0.9166   0.0817   0.0001   0.0001   0.1077
 0001 42.6846   0.0001   0.8629   0.9188   0.0706   0.0002   0.0161   0.1840 
 0002 42.5846   0.0001   1.0888   0.8851   0.0544   0.0002   0.0161   0.1294
 0003 42.6181   0.0001   0.9546   0.9162   0.0535   0.0002   0.0161   0.1331
 0004 42.4007   0.0001   1.1028   0.9472   0.0466   0.0003   0.0161   0.2360
 ......
 irecv calls: 400 time: 0.624307 s datacnt 632836800 
 ......
 isend calls: 400 time: 0.00628472 s 1.57118e-05 s/call
 ........
 wait calls: 800 time: 0.00118888 s avg datacnt1.57814e+06
 ........
上記はランク0の解析です。~
irecvが400回コールされ、通信時間は0.624307秒、~
isendが400回コールされ、通信時間は0.006284秒、~
waitが800回コールされ、通信時間は、0.0011888秒~
~
エクセルへコピーして面グラフで表示します。
#ref(MPInside.jpg,left,nowrap,80%)

--横軸がランク番号、縦軸が経過時間を表します。
--MPIルーチンの実行時間が色分けされます。
--上図では、計算部分とMPI_Alltoallvの時間が大部分を占めていることがわかります。
--MPIルーチンの実行時間には、実際の通信時間と待ち時間が含まれています。


トップ   新規 一覧 単語検索 最終更新   ヘルプ