•
非ブロック型通信– post-send, complete-send
– post-receive, complete-receive
• Post-{send,recv}
で送信受信操作を開始• Complete-{send,recv}
で完了待ち•
デッドロックを防ぐ•
計算と通信のオーバラップを可能に–
マルチスレッドでも可能だが,しばしばより効率的非ブロック型通信
• Send/recv
を実行して、後で終了をチェックする通信方法–
通信処理が裏で行える場合は計算と通信処理のオーバラップが可能int MPI_Isend( void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request ) int MPI_Irecv( void *buf, int count, MPI_Datatype datatype,
int source, int tag, MPI_Comm comm, MPI_Request *request )
int MPI_Wait ( MPI_Request *request, MPI_Status *status)
1 対 1 通信の通信モード
•
ブロック型,非ブロック型通信のそれぞれに以下の通信 モードがある–
標準モード• MPI処理系が送信メッセージをバッファリングするかどうか決定する。
利用者はバッファリングされることを仮定してはいけない
–
バッファモード• 送信メッセージはバッファリングされる
• 送信はローカルに終了
–
同期モード• 送信は対応する受信が発行されたら完了(ランデブー通信)
• 送信はノンローカルに終了
– Ready
モード• 対応する受信が発行されているときだけ送信が始まる
• 送受信のハンドシェークを省ける
メッセージの交換
•
ブロック型• MPI_Send
がバッファリングさ れる場合のみ実行可能– されない場合はデッドロック
• MPI_Sendrecv
を利用する•
非ブロック型•
必ず実行可能•
ポータブルMPI_Send(送信先、データ) MPI_Recv(受信元、データ)
MPI_Isend(送信先、データ、リクエスト) MPI_Recv(受信元、データ)
MPI_Waitall(リクエスト)
1 対 1 通信の注意点(1)
•
メッセージ到着順–
(2
者間では)メッセージは追い越されない– 3
者間以上では追い越される可能性があるP0 P1 P0 P1 P2
到着順は 保証される
到着順は 保証されない P2は送信元か タグを指定する 必要がある
1 対 1 通信の注意点(2)
•
公平性–
通信処理において公平性は保証されないP0 P1 P2
P1
はP0
からのメッセージばかり受信し、P2
からのメッセー ジがstarvation
を引き起こす可能性有りP0
はP1
に送信P2
はP1
に送信並列処理の例(3): laplace
• Laplace
方程式の陽的解法–
上下左右の4
点の平均で、更新していく
– Old
とnew
を用意して直前 の値をコピー–
典型的な領域分割–
最後に残差をとる𝜕𝜕 2 𝑓𝑓
𝜕𝜕𝑥𝑥 2 + 𝜕𝜕 2 𝑓𝑓
𝜕𝜕𝑦𝑦 2 = 0
𝑓𝑓 0, −1 + 𝑓𝑓 −1,0 + 𝑓𝑓 1,0 + 𝑓𝑓 0,1 − 4𝑓𝑓 0,0 = 0
離散化
*𝑓𝑓(−1,0) means 𝑓𝑓(𝑥𝑥 − ∆𝑥𝑥 , 𝑦𝑦)
𝑓𝑓(0,0)
𝑛𝑛𝑛𝑛𝑛𝑛= 1
4 𝑓𝑓
𝑜𝑜𝑜𝑜𝑜𝑜0, −1 + 𝑓𝑓
𝑜𝑜𝑜𝑜𝑜𝑜−1,0 + 𝑓𝑓
𝑜𝑜𝑜𝑜𝑜𝑜1,0 + 𝑓𝑓
𝑜𝑜𝑜𝑜𝑜𝑜0,1
行列分割と隣接通信
•
二次元領域をブロッ ク分割•
境界の要素は隣の プロセスが更新•
境界データを隣接 プロセスに転送P0
P1
P2
P3
プロセストポロジ
int MPI_Cart_create(MPI_Comm comm_old, int ndims, int *dims, int *periods, int reorder,
MPI_Comm *comm_cart);
• ndims
次元のハイパーキューブのトポロジをもつコミュニケータ
comm_cart
を作成• dims
はそれぞれの次元のプロセス数• periods
はそれぞれの次元が周期的かどうか• reorder
は新旧のコミュニケータでrank
の順番 を変更するかどうかシフト通信の相手先
int MPI_Cart_shift(MPI_Comm comm, int direction, int disp, int *rank_source, int
*rank_dest);
• direction
はシフトする次元– ndims
次元であれば0
~ndims-1
• disp
だけシフトしたとき,受け取り先がrank_source
,送信先がrank_dest
に返る•
周期的ではない場合,境界を超えるとMPI_PROC_NULL
が返される/* calculate process ranks for ‘down’ and ‘up’ */
MPI_Cart_shift(comm, 0, 1, &down, &up);
/* recv from down */
MPI_Irecv(&uu[x_start-1][1], YSIZE, MPI_DOUBLE, down, TAG_1, comm, &req1);
/* recv from up */
MPI_Irecv(&uu[x_end][1], YSIZE, MPI_DOUBLE, up, TAG_2, comm, &req2);
/* send to down */
MPI_Send(&u[x_start][1], YSIZE, MPI_DOUBLE, down, TAG_2, comm);
/* send to up */
MPI_Send(&u[x_end-1][1], YSIZE, MPI_DOUBLE, up, TAG_1, comm);
ドキュメント内
MPI
(ページ 30-40)