ル、次のエントリへのポインタおよびパックされたメッセージデータなどを含んでいる。エント リは、バッファ内の連続した位置に格納される。キューの末尾とキューの先頭の間には、空き領 域があってもよい。
バッファ送信呼び出しは、以下のコードのように実行されることになる。
先頭から末尾に向かって、まだ完了していない要求の最初のエントリに達するまで、すで に完了した通信の全てのエントリを消去しながら、PMEキューを順に移動する。つまり、
そのエントリを指すようにキューの先頭を更新する。
新しいメッセージのエントリを格納するために必要なバイト数nを計算する。nの上限は、
以下のようにして計算できる。MPI BSENDで使用されるcount,datatype,comm引数を 持つMPI PACKSIZE(count,datatype,comm,size)関数の呼び出しは、メッセージデー
タのバッファリングに必要な領域の上限を返す。(3.13節参照)MPI定数MPI BSENDOVERHEAD は、このエントリ(例えば、ポインタやエンベロープ情報)で消費される追加領域の上限
を与える。
バッファ内(キューの末尾に続く領域、あるいは、キューの末尾がバッファの最後に近す ぎる場合にはバッファの最初の領域)で次の連続するnバイトの空き領域を探す。
領域が見つからない場合には、バッファオーバーフローエラーを出す。
PMEキューの最後に、要求ハンドル、次のポインタ、パックされたメッセージデータを 含む新しいエントリを(連続した領域で)追加する。データのパックには、MPI PACKが 使用される。
パックされたデータに対し、ノンブロッキング送信(標準モード)を発行する。
戻る。
3.7. ノンブロッキング通信 47 時点で、送信側での計算と並行させて送信側のメモリーからのデータの転送を行うことができる であろう。同様に、ノンブロッキング受信開始呼出しは受信作業を起動するが完了はしない。こ の呼出しはメッセージが受信バッファに格納される前に戻される。受信操作を完了させ、データ が受信バッファに受け取られたことを確認するためには、別の受信完了の呼出しが必要である。
適当なハードウエアを使えば、受信が起動され終了する以前に、受信側のメモリーへのデータの 転送を計算と並行させて行えるであろう。ノンブロッキング受信を使用すると、情報は早い時 点で受信バッファの位置で提供されているので、システムのバッファリングやメモリーからメモ リーへのコピーを避けることもできるであろう。
ノンブロッキング送信開始の呼出しは、ブロック送信と同じ標準、バッファ、同期、レディ の4つのモードを使用することができる。これらはブロック通信のときと同じ意味を持ってい る。レディ以外のすべてのモードでは、対応する受信が発行されたかどうかにかかわらず送信を 開始することができる。ノンブロッキングのレディ・モードでの送信は、対応する受信が発行さ れたときにのみ開始することができる。すべての場合において、送信開始呼出しはローカルであ り、他のプロセスの状態によらずただちに戻ってくる。もしその呼出しがシステムの資源の何か を使い果たしてしまったときは、失敗となりエラーコードが返される。MPI の高品質な実装に おいては、このようなことは\病的"な場合にのみ起こるようになっていなければならない。す なわちMPI の実装は、多くの保留になっているノンブロッキング操作をサポートすることがで きなければならない。
送信完了の呼出しは、データが送信バッファからコピーされ終わったときに戻ってくる。こ のことは送信モードによっては付加的な意味をもつことがある。
送信モードが同期なら、送信は対応する受信が開始したとき、すなわち受信が発行され送信 と対応されたときにのみ完了することができる。この場合には送信完了はノンローカルである。
同期ノンブロッキング送信は、もしノンブロッキング受信と対応がとられれば、受信完了呼出し が発生する前に完了することができることに注意されたい。(送信側が転送が完了することを
\知れ"ば、受信側が転送が完了することを\知る"以前であってもただちに完了する。)
送信モードがバッファのときは、もし保留中の受信がなければメッセージはバッファリング されなければならない。この場合には送信完了呼出しはローカルであり、対応する受信の状態に よらず継続されなければならない。
送信モードが標準のときは、もしメッセージがバッファリングされているなら、送信完了呼 出しは対応する受信が起こる前に戻されることがある。一方、対応する受信が発生し、メッセー ジが受信バッファにコピーされるまで送信完了は終了しないこともありうる。
ノンブロッキング送信はブロッキング受信と対応させることができ、逆も可能である。
ユーザへのアドバイス 送信操作の完了は、標準モードに対しては遅延することがあり、同 期モードに対しては対応する受信が発行されるまで遅延しなければならない。この2つの 場合においては、ノンブロッキング送信を使用することにより、送信側は受信側より先に
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
進むことができ、2つのプロセスの速度の揺らぎに対し、計算がより強い耐性を持つ。
バッファ・モードとレディ・モードにおけるノンブロッキング送信はより限定された効果 しか持たない。ノンブロッキング送信は可能な限りすぐに戻るが、ブロック送信はデータ が送信側のメモリーからコピーされた後に戻る。この場合にはデータのコピーを計算と平 行して行うことができるときにのみ、ノンブロッキング送信を使用することが有利になる。
メッセージパッシングモデルは、通信は送信側によって起動されるということを意味して いる。もし送信側が通信を起動したときに受信がすでに発行されているならば、通信は一 般的により小さなオーバーヘッドを持つ。(データを受信側のバッファに直接移動させる ことができ、保留中の送信要求を待つ必要がない。)しかしながら、受信操作は対応する 送信が起こった後にのみ完了することができる。ノンブロッキング受信を使用することに より、送信を待っている間も受信側をブロックすることなく、より低い通信オーバーヘッ ドが実現できる。(ユーザへのアドバイスの終わり)
3.7.1 通信オブジェクト
ノンブロッキング通信は、通信操作を識別するために不透明な要求オブジェクトを使用し、通信 を起動する操作と終了させる操作を対応させる。これらはハンドルを通してアクセスされるシス テムオブジェクトである。要求オブジェクトは、送信モード、それに対応した通信バッファ、そ のコンテキスト、送信のために使用されるタグや送信先引数、受信のために使用されるタグや送 信元引数などのさまざまな通信操作の性質を識別する。さらに、このオブジェクトは保留中の通 信操作の状態についての情報を記憶する。
3.7.2 通信の起動
我々はブロック通信に対するのと同じ名前付けの規約を使用する。すなわちバッファ、同期、レ ディモードに対しB、S、R とい接頭辞を使う。さらにI(即座 immediate)という接頭辞が付 くと呼出しがノンブロッキングであることを意味する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
3.7. ノンブロッキング通信 49
MPI ISEND(buf,count, datatyp e, dest, tag, comm,request)
入力 buf 送信バッファの先頭アドレス(選択型)
入力 count 送信バッファの中の要素の数(整数型)
入力 datatype 各送信バッファの要素のデータ型(ハンドル)
入力 dest 送信先のランク(整数型)
入力 tag メッセージタグ(整数型)
入力 comm コミュニケータ(ハンドル)
出力 request 通信要求(ハンドル)
int MPI Isend(void* buf, int count, MPI Datatype datatype, int dest,
int tag, MPI Comm comm, MPI Request *request)
MPI ISEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERROR)
<type> BUF(*)
INTEGER COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERROR
標準モードのノンブロッキング送信を開始する。
MPI IBSEND(buf,count,datatyp e, dest, tag, comm,request)
入力 buf 送信バッファの先頭アドレス(選択型)
入力 count 送信バッファの中の要素の数(整数型)
入力 datatype 各送信バッファの要素のデータ型(ハンドル)
入力 dest 送信先のランク(整数型)
入力 tag メッセージタグ(整数型)
入力 comm コミュニケータ(ハンドル)
出力 request 通信要求(ハンドル)
int MPI Ibsend(void* buf, int count, MPI Datatype datatype, int dest,
int tag, MPI Comm comm, MPI Request *request)
MPI IBSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERROR)
<type> BUF(*)
INTEGER COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERROR 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
バッファ・モードのノンブロッキング送信を開始する。
MPI ISSEND(buf,count, datatyp e, dest, tag, comm,request)
入力 buf 送信バッファの先頭アドレス(選択型)
入力 count 送信バッファの中の要素の数(整数型)
入力 datatype 各送信バッファの要素のデータ型(ハンドル)
入力 dest 送信先のランク(整数型)
入力 tag メッセージタグ(整数型)
入力 comm コミュニケータ(ハンドル)
出力 request 通信要求(ハンドル)
int MPI Issend(void* buf, int count, MPI Datatype datatype, int dest,
int tag, MPI Comm comm, MPI Request *request)
MPI ISSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERROR)
<type> BUF(*)
INTEGER COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERROR
同期モードのノンブロッキング送信を開始する。
MPI IRSEND(buf, count,datatyp e,dest, tag, comm, request)
入力 buf 送信バッファの先頭アドレス(選択型)
入力 count 送信バッファの中の要素の数(整数型)
入力 datatype 各送信バッファの要素のデータ型(ハンドル)
入力 dest 送信先のランク(整数型)
入力 tag メッセージタグ(整数型)
入力 comm コミュニケータ(ハンドル)
出力 request 通信要求(ハンドル)
int MPI Irsend(void* buf, int count, MPI Datatype datatype, int dest,
int tag, MPI Comm comm, MPI Request *request)
MPI IRSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERROR)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47