Concepts in Parallelisation

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