TM 並列プログラミング •並列処理での性能向上について •共有メモリ型プログラミング(OpenMP) •メッセージパッシング型プログラミング(MPI) 並列化の利点 TM • プログラムの経過時間の短縮 cpu 時間 1 processor 通信のオーバーヘッド 4 processors start 経過時間 finish • オーバーヘッド: – – – – – 全体のcpu 時間は増加 通信 同期 アルゴリズムの変更に伴う処理の増加 コードのなかの並列化できない部分 経過時間の短縮 経過時間 2 並列処理での性能向上 TM • コード全体に対する逐次処理の割合に因って、スピードアップ に上限ができてしまう 並列処理 70% 逐次処理 30% 並列処理 99% 並列処理 90% 16CPU 16CPU 16CPU 2.9倍 Speedup 6.4倍 Speedup 13.9倍 Speedup 逐次処理 10% 逐次処理 1% 3 並列実行プログラミング TM • Origin3800でサポートされているプログラミングモデル – 共有メモリプログラミング • 自動並列化 コンパイルオプション-apo を指定 • OpenMP並列化指示行 基本的には、ループに対して並列化を指示 – メッセージパッシング • MPI、PVM、SHMEM 4 自動並列化とOpenMP TM • コンパイラがコードをうまく並列化してくれれば... ユーザはOpenMPを知らなくてもOK しかし、... • 実用コードではコンパイラだけではうまく並列化されない 場合がある 例えば、 do i = 1, n A(IB(i)) = ... ... enddo 自動並列化とOpenMP指示行との併用も可能 全てのイタレーションで IB(i) の値 が異なっていれば並列化可能 コンパイラは確認できない ユーザが確認できれば並列 化指示行を指定 5 ループを並列化する指示行(1) TM 指示行に続くイタレーションを各プロセスに分散 – C/C++ • 大文字と小文字の区別があります。 • 1行に収まらない場合は、\(バックスラッシュ)で改行をエスケープします。 #pragma omp parallel for private(変数p1、...) shared(変数s1、...)] { 並列実行領域 for (...) } 同じ意味 #pragma omp parallel for \ private(変数p1、...) shared(変数s1、...)] { for (...) 並列実行領域 } 6 ループを並列化する指示行(2) TM 指示行に続くイタレーションを各プロセスに分散 – Fortran • 大文字、小文字どちらで書いても構いません。 • 1行に収まらない場合は、!$omp& を指定して次行に続けます。 !$OMP PARALLEL DO PRIVATE(変数p1、変数p2、...) SHARED(変数s1、変数s2、...) DO I=i1,i2,i3 並列実行領域 block ENDDO 同じ意味 !$OMP PARALLEL DO !$OMP& PRIVATE(変数p1、変数p2、...) SHARED(変数s1、変数s2、...) DO I=i1,i2,i3 block 並列実行領域 ENDDO 7 private変数とshared変数(1) TM 並列実行領域内の変数の属性を定義: • private – – – – プロセス毎にプライベート 新たに記憶領域が確保される 並列実行領域内だけでアクセス可能 初期値は未定義 • shared – 共有変数 – 全プロセスは同じメモリ位置にアクセス 8 private変数とshared変数(2) TM index変数はprivate !$omp parallel do private(i, tmp) shared(max, A, B, C, n) do i = 1, n tmp = i + max C(i) = A(i) * B(i) + tmp enddo print *, ‘C(n) = ‘, C(n) ... ... 9 データ配置について TM – 全てのデータ(ページ単位)は「ファーストタッチ」で 配置されます。 – もし、初期化ループが逐次実行領域であれば該当 データは1ノードに置かれます。 – 並列実行領域では全プロセッサが1ノードへアクセ スすることになり、プログラムの性能が低下します。 初期化ループも 並列化すること CPU CPU CPU CPU ASIC Memory ASIC Memory CPU CPU CPU CPU real*8 A(n), B(n), C(n), D(n) !$omp parallel do private(i) do i=1, n A(i) = 0. B(i) = i/2 C(i) = i/3 D(i) = i/7 enddo !$omp parallel do private(i) do i=1, n A(i) = B(i) + C(i) + D(i) enddo 10 OpenMPプログラムのコンパイル TM •コンパイラによる自動並列化 – コンパイルとリンクを1ステップで行なうとき % f90 –apo prog.f – コンパイルとリンクを別々のステップで行なうとき % f90 –apo –c prog.f % f90 –mp prog.o 並列化制御のライブラリをリンクするため-mpが必要 •OpenMP指示行を有効にする – OpenMP指示行を有効にして、かつ自動並列化も指示 % f90 –apo prog.f – OpenMP指示行だけを有効にする % f90 –mp prog.f 11 OpenMPプログラムの実行 • TM 環境変数に実行プロセッサ数を指定 %setenv OMP_NUM_THREADS 4 %a.out • 実行プロセッサ数のデフォルト 8プロセッサ 12 MPI プログラムのコンパイルと実行 TM •MPIライブラリのリンクを指示してコンパイル % f90 ex_mpi.f -lmpi •バッチジョブとして実行するとき % bsub –q <queue-name> –J <job-name> –n N mpijob a.out •会話型ジョブとして実行するとき % mpirun –np N a.out N は実行プロセッサ数 –バックグラウンドジョブとして実行するとき % mpirun –np N a.out < /dev/null & (コマンド行で指定する入力ファイルがある場合は、 /dev/null ファイルの指定は必要ありません。) •N+1 のプロセスが生成されます。そのうちの1プロセスは“lazy”プロセスと 呼ばれ、ほとんど処理をしません。 ( mpi_init() コールでブロックされて 全プロセスがmpi_finalize()をコールすると終了) 13 MPIプログラムの性能解析 TM ルーチンレベルの解析: % mpirun -np N ssrun -fpcsampx a.out % prof –h a.out.fpcsampx.[mf]PID プログラム全体の解析: (会話型ジョブとして実行するとき) % mpirun -np N perfex -a -y –mp -o perfex.out a.out • perfex.out.#procidファイルに各プロセスの解析結果が出力されます • perfex.outファイルに全プロセスの解析結果の集計が出力されます アカウント情報の収集: (会話型ジョブとして実行するとき) % ja % mpirun -np N a.out % ja –c –s -t 14 OpenMPとMPI TM (並列プログラミングモデルの比較) • OpenMP (共有メモリプログラミング) – – – – コンパイラによる自動並列化が可能 段階的な並列処理の適用が可能 既存の逐次処理用のプログラムからの変更が少ない ループレベルの並列化 ― スケーラビリティに限界がある • MPI (メッセージパッシング) – スケーラビリティが高い – 段階的に並列化を進めることはできない – プログラミングは難しい どちらのプログラミングモデルを選択すべきでしょうか • アプリケーションの性質、ユーザの好みに因るところが大きい • 逐次実行プログラムを並列化したいという場合はOpenMPをお奨めします。 15
© Copyright 2025 ExpyDoc