例:各例:各例:各
N, steps の表示
for (step=0; step<steps; step++) { 問題①「
問題①「 Broadcast Broadcast 」 」 calculate_forces();
move_bodies();
問題②「
問題②「 Gather Gather 」 」 ビットマップ出力 }
}
独自型の定義・登録
• double 7 個からなる ”MPI_BODY” 型の定義・登録
– Send/Recv の際、要素の型として使えるようになる=書きやすい! 書きやすい!
typedef struct { double px, py;
double vx, vy;
double fx, fy;
double m;
} Body; // この構造体を単位として Send/Recv するため MPI_Datatype MPI_BODY;
MPI_Type_contiguous(7, MPI_DOUBLE, &MPI_BODY);
MPI_Type_commit(&MPI_BODY);
デモアプリの使い方
• コンパイル
– mpicc -o nbody nbody_mpi.c
error_wrapper.c Disk.c – make も使えます
• 入力
– ./nbody < 入力ファイル > <
ステップ数 >
• random5000.data
• 100
• 出力
– 標準出力
• シミュレーション全体に 何秒かかったか
– ビットマップファイル
• 各シミュレーションステップの 質点の座標をプロット
• ./STEP????.bmp
第三回第三回
第三回第三回MPI実践セミナー実践セミナー実践セミナー実践セミナー Copyright (C)
質点 質点 質点
質点 5000 個 個 個 個 ランダム配置 ランダム配置 ランダム配置 ランダム配置
余りは末尾のプロセスが担当
問題①「 Broadcast 」を Send/Recv で書こう
// // (1) Broadcast bodies from root process to the other processes // if ( rank == root ) {
// // TODO:
// Send all bodies to non-root processes } else { //
// // TODO:
// Receive all bodies from the root process } //
rank 0
1
2
3
問題②「 Gather 」を Send/Recv で書こう
// // (2) Gather states of the bodies to the root process // if ( rank == root ) {
// // TODO:
// Receive each bodies from non-root processes } else { //
// // TODO:
// Send my bodies to the root process // // HINT:
// All bodies are stored as bodies[].
// Indices of my bodies are between myStart[rank] and myEnd[rank].
// Use MPI_BODY as element type.
} //
第三回第三回
第三回第三回MPI実践セミナー実践セミナー実践セミナー実践セミナー Copyright (C)
rank 0
1
2
3
実行時間書き込みページ
nproc 実行時間 [ 秒 ] 速度向上率
1 1.00
2
4
並列版の性能スケーラビリティ
第三回第三回
第三回第三回MPI実践セミナー実践セミナー実践セミナー実践セミナー Copyright (C) 1.00
1.98
3.88
5.78
7.44
9.02
10.13
11.46 12.11
0 2 4 6 8 10 12 14 16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
速 度 向 上 率 速 度 向 上 率 速 度 向 上 率 速 度 向 上 率
nproc
Linear 速度向上率 多項式近似
答え合わせ①
if ( rank == root ) {
for ( i = 1; i < nproc; i++ ) {
MPI_Send(bodies, N, MPI_BODY, i, 1, MPI_COMM_WORLD);
} else { }
MPI_Recv(bodies, N, MPI_BODY,
root, 1, MPI_COMM_WORLD, &status);
}
rank が が が が root の の の の プロセスから プロセスから プロセスから プロセスから
Recv
rank が が が が 1 以上の 以上の 以上の 以上の プロセスへ プロセスへ プロセスへ プロセスへ
Send
答え合わせ②
if ( rank == root ) {
for ( i = 1; i < nproc; i++ ) {
MPI_Recv(&bodies[myStart[i]], myEnd[i] - myStart[i],
MPI_BODY, i, 2, MPI_COMM_WORLD, &status);
} else { }
MPI_Send(&bodies[myStart[rank]], myEnd[rank] - myStart[rank],
MPI_BODY, root, 2, MPI_COMM_WORLD);
}
rank が が が が root の の の の プロセスへ プロセスへ プロセスへ プロセスへ
Send
rank が が が が 1 以上の 以上の 以上の 以上の プロセスから プロセスから プロセスから プロセスから
Recv
第三回第三回
第三回第三回MPI実践セミナー実践セミナー実践セミナー実践セミナー Copyright (C)
集合通信関数を使うと
MPI_Gather(&bodies[myStart[rank]], myEnd[rank]-myStart[rank], MPI_BODY, &bodies[root],
myEnd[rank]-myStart[rank], root, MPI_COMM_WORLD);
rank 0 1 2 3
C
localC localC localC localC
MPI_Recv x4
MPI_Send
MPI_Send MPI_Send MPI_Send
MPI総括
• 並列プログラム開発の標準的 API
• 基本「データを Send/Recv する」
• 並列性の把握、データ分配・粒度がカギ
– とにかくネットワーク通信を控えよう ネットワーク通信を控えよう
第三回第三回
第三回第三回MPI実践セミナー実践セミナー実践セミナー実践セミナー Copyright (C)