ユーザへのアドバイス 標準送信が使用されるときには、バッファ領域が使用できないため に両方のプロセスがブロックされる場合に、デッドロック状況が発生する。同期モードが 使用される場合にも、同様のことが必ずおこる。バッファモードが使用され、十分なバッ ファ領域が利用できない場合には、プログラムは完了しない。しかしながら、デッドロッ ク状況は起こらず、バッファオーバーフローになる。
プログラムが完了するために、メッセージのバッファリングが必要ない場合には、プログ
ラムは\安全"である。そのようなプログラムでは、全ての送信を同期送信に置き換える
ことができ、しかも依然としてプログラムは正しく走る。この保守的なプログラミングス タイルは、最良のポータビリティを提供する。これは、プログラムの完了が、使用可能な バッファ領域の量や、使用される通信プロトコルに依存しないからである。
多くのプログラマは活動の余地が広いことを好み、例3.9に示されるような、\危険な"プ ログラミングスタイルが使用できることを好む。そのような場合には、標準送信の使用は、
性能と頑健さの最良の妥協点を提供するだろう。つまり、質の高い実装では、\通常の"プ ログラムがデッドロックしないように、十分なバッファリングが提供される。バッファ送 信モードは、より多くのバッファリングを必要とするプログラムに対して、また、プログ ラマがもっと制御したい状況において使用される。このモードは、バッファオーバーフロー 状況の方が、デッドロック状況よりも診断しやすいため、デバッギングの目的のためにも 使用される。
3.7節で記述されるように、送出メッセージのバッファリングの必要を避けるために、ノン ブロッキングメッセージ通信操作を使用することができる。このことにより、バッファ領 域の不足によるデッドロックを回避でき、計算と通信との重ね合わせを許し、また、バッ ファのアロケーションとメッセージをバッファへコピーするオーバーヘッドを回避するこ とにより、性能を改善する。(ユーザへのアドバイスの終わり)
3.6
バッファのアロケーションと使用法
ユーザーは、バッファモードで送られるメッセージのバッファリングに使用されるバッファを指 定することができる。
MPI BUFFER ATTACH( buer,size)
入力 buer バッファの先頭アドレス(選択型)
入力 size バッファサイズ(バイト)(整数型)
int MPI Buffer attach( void* buffer, int size) 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 BUFFER ATTACH( BUFFER, SIZE, IERROR)
<type> BUFFER(*)
INTEGER SIZE, IERROR
送出メッセージのバッファリングに使用するユーザメモリ内のバッファをMPI に与える。
このバッファは、バッファモードで送られるメッセージによってのみ使用される。同時には、た だ1つのバッファのみが、1つのプロセスに貼り付けられる。
MPI BUFFER DETACH( buer,size)
出力 buer バッファの先頭アドレス(選択型)
出力 size バッファサイズ(バイト)(整数型)
int MPI Buffer detach( void** buffer, int* size)
MPI BUFFER DETACH( BUFFER, SIZE, IERROR)
<type> BUFFER(*)
INTEGER SIZE, IERROR
現在 MPI に付随しているバッファを切り離す。この呼び出しは、切り離されたバッファの アドレスとサイズを返す。現在バッファにある全てのメッセージが転送されるまで、この操作は ブロックする。この関数が戻った上で、ユーザーはこのバッファにより占められた領域を再利用 したり、非アロケートしたりできる。
例 3.10 バッファリングに依存した交換
#define BUFFSIZE 10000
int size
char *buff;
MPI_Buffer_attach( malloc(BUFFSIZE),BUFFSIZE);
/* 10000バイトのバッファは今やMPI_Bsendで使用可能である */
MPI_Buffer_detach( &buff, &size);
/* バッファサイズは0になる */
MPI_Buffer_attach( buff, size);
/* 10000バイトのバッファは再び利用可能となる */
ユーザへのアドバイス C言語関数MPI Buer attachとMPI Buerdetachは両方とも第
1引数にvoid* 型を持つが、これらの引数は異なった方法で使われる。つまり、この呼び
出しがポインタ値を返せるように、MPI Buerattachへはバッファのポインタが渡され、
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
3.6. バッファのアロケーションと使用法 45
MPI Buer detachへはポインタのアドレスが渡される。(ユーザへのアドバイスの終わ
り)
根拠 複雑な型変換を避けるため、両引数はvoid*型として定義されている。(各々がvoid*
とvoid**となるのではなく)例えば、最後の例では、char**型をもつ&buは、型変換 される事なく引数としてMPI Buerdetachに渡される。正式な引数がvoid**を持つ場合 には、呼び出しの前後で型変換を行う必要がある。(根拠の終わり)
この節の記述は、バッファモード送信におけるMPIの動作について説明する。現在バッファ が付随していない場合、MPI はプロセスにサイズ0のバッファが付随しているかのように動作 する。
MPI は、送信メッセージデータが、送信プロセスにより指定されたバッファ領域へ巡回的 な連続領域アロケーションの原則に従ってバッファリングされるために必要な量のバッファを、
送出メッセージに対して、提供しなければならない。以下では、この原則を定義するモデル実装 について概説する。MPI は、より多くのバッファリングを提供するかもしれないし、以下に記 述されるものより優れたバッファアロケーションアルゴリズムを使用するかもしれない。一方、
MPI は、以下に記述した単純バッファアロケータが領域を使いきった時にはいつでもエラーシ グナルを返すかもしれない。特に、プロセスに明示的に付随されたバッファがない時には、バッ ファ送信はエラーを引き起こすかもしれない。
MPI は、標準モード送信で実行されるバッファリングについて、問い合わせや制御のため のメカニズムを提供しない。そのような情報は、ベンダーによる実装で提供されることが望まし い。
根拠 バッファ通信の可能な実装は、多岐にわたる。バッファリングは、送信側、受信側あ るいは両方で行うことができるし、バッファは1つの送信・受信対専用になったり、全て の通信で共有することもできるし、バッファリングは実メモリかあるいは仮想メモリで行 うこともできるし、専用のメモリを使ったり、他のプロセスとの共有メモリを使うことも できるし、バッファは静的にアロケートしたり、動的にアロケートしたりもできる。これ ら全ての選択に互換性をもつような、バッファリングについての問い合わせや制御を行う ポータブルなメカニズムを提供することは容易ではないが、これらは有益な情報を提供し ている。(根拠の終わり)
3.6.1 バッファモードのモデル実装
モデル実装は、3.13節で記述されるパッキング関数とアンパッキング関数、そして3.7節で記述 されるノンブロッキング通信関数を使用する。
保留中のメッセージエントリ(pending message entries=PME)の循環キューが整備され ると仮定する。各々のエントリは、保留中のノンブロッキング送信を識別する通信要求ハンド
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
ル、次のエントリへのポインタおよびパックされたメッセージデータなどを含んでいる。エント リは、バッファ内の連続した位置に格納される。キューの末尾とキューの先頭の間には、空き領 域があってもよい。
バッファ送信呼び出しは、以下のコードのように実行されることになる。
先頭から末尾に向かって、まだ完了していない要求の最初のエントリに達するまで、すで に完了した通信の全てのエントリを消去しながら、PMEキューを順に移動する。つまり、
そのエントリを指すようにキューの先頭を更新する。
新しいメッセージのエントリを格納するために必要なバイト数nを計算する。nの上限は、
以下のようにして計算できる。MPI BSENDで使用されるcount,datatype,comm引数を 持つMPI PACKSIZE(count,datatype,comm,size)関数の呼び出しは、メッセージデー
タのバッファリングに必要な領域の上限を返す。(3.13節参照)MPI定数MPI BSENDOVERHEAD は、このエントリ(例えば、ポインタやエンベロープ情報)で消費される追加領域の上限
を与える。
バッファ内(キューの末尾に続く領域、あるいは、キューの末尾がバッファの最後に近す ぎる場合にはバッファの最初の領域)で次の連続するnバイトの空き領域を探す。
領域が見つからない場合には、バッファオーバーフローエラーを出す。
PMEキューの最後に、要求ハンドル、次のポインタ、パックされたメッセージデータを 含む新しいエントリを(連続した領域で)追加する。データのパックには、MPI PACKが 使用される。
パックされたデータに対し、ノンブロッキング送信(標準モード)を発行する。
戻る。