スコープ固有の ID を使用してブロックにマークを付けます。
.-,---------. V | >>-#--pragma--block_loop--(--n--,----name_list-+--)------------><
ここで、
n | 反復グループのサイズの整数式です。 |
name_list | #pragma loopid ディレクティブを使用して作成できる固有 ID です。name_list を指定しないと、#pragma block_loop ディレクティブの後の最初の for ループ、または block_loop でブロッキングが発生します。 |
name は、スコープ単位内で固有の ID です。
ループ・ブロッキングが発生するには、#pragma block_loop ディレクティブが for ループに先行している必要があります。
ブロッキング・ループに unroll、unroll_and_fuse、または stream_unroll ディレクティブを指定すると、ブロッキング・ループが実際に作成された場合、ブロッキング・ループがそれぞれアンロール、アンロールおよびフューズ、またはストリーム・アンロールされます。それ以外の場合、このディレクティブは何の効果もありません。
ブロックされたループに unroll_and_fuse または stream_unroll ディレクティブを指定すると、ディレクティブはブロッキング・ループの作成後に、ブロックされたループに適用されます。ブロッキング・ループが作成されないと、対応する block_loop ディレクティブが指定されていないかのように、このディレクティブがブロッキングを意図したループに適用されます。
#pragma block_loop を複数回指定したり、同じ for ループに対してこのディレクティブを nounroll、unroll、nounrollandfuse、unrollandfuse、または stream_unroll プラグマ・ディレクティブと結合してはいけません。また、単一のブロック・ループ・ディレクティブに複数の unroll ディレクティブを適用しないでください。
すべての block_loop ディレクティブの処理は常に、いずれかの unroll ディレクティブによって示されるアンロールの実行前に完了します。
例 1 - ループのタイル表示
#pragma block_loop(50, mymainloop) #pragma block_loop(20, myfirstloop, mysecondloop) #pragma loopid(mymainloop) for (i=0; i < n; i++) { #pragma loopid(myfirstloop) for (j=0; j < m; j++) { #pragma loopid(mysecondloop) for (k=0; k < m; k++) { ... } } }
例 2 - ループのタイル表示
#pragma block_loop(50, mymainloop) #pragma block_loop(20, myfirstloop, mysecondloop) #pragma loopid(mymainloop) for (i=0; i < n; n++) { #pragma loopid(myfirdstloop) for (j=0; j < m; j++) { #pragma loopid(mysecondloop) for (k=0; k < m; k++) { ... } } }
例 3 - ループの交換
for (i=0; i < n; i++) { for (j=0; j < n; j++) { #pragma block_loop(1,myloop1) for (k=0; k < m; k++) { #pragma loopid(myloop1) for (l=0; l < m; l++) { ... } } } }
例 4 - マルチレベル・メモリー階層のためのループのタイル表示
#pragma block_loop(l3factor, first_level_blocking) for (i=0; i < n; i++) { #pragma loopid(first_level_blocking) #pragma block_loop(l2factor, inner_space) for (j=0; j < n; j++) { #pragma loopid(inner_space) for (k=0; k < m; k++) { for (l=0; l < m; l++) { ... } } } }
例 5 - ブロッキング・ループのアンロールとフューズ
#pragma unrollandfuse #pragma block_loop(10) for (i = 0; i < N; ++i) { }
この場合、ブロック・ループ・ディレクティブが無視されると、アンロール・ディレクティブは何の効果も持ちません。
例 6 - ブロックされたループのアンロール
#pragma block_loop(10) #pragma unroll(2) for (i = 0; i < N; ++i) { }
この場合、ブロック・ループ・ディレクティブが無視されても、非ブロック化されたループはアンロールされます。ブロッキングが発生した場合は、その発生後、 アンロール・ディレクティブはブロックされたループに適用されます。
例 1 - 未定義ループ ID の Block_loop
#pragma block_loop(50, myloop) for (i=0; i < n; i++) { } Referencing myloop is not allowed, since it is not in the nest and may not be defined.
例 2 - 同一ループ・ネスト内にないループ ID の Block_loop
for (i=0; i < n; i++) { #pragma loopid(myLoop) for (j=0; j < i; j++) { ... } } #pragma block_loop(myLoop) for (i=0; i < n; i++) { ... } Referencing myloop is not allowed, since it is defined in a different loop nest (nesting structure).
例 3 - ブロッキング・ループに指定された矛盾するアンロール・ディレクティブ
#pragma unrollandfuse(5) #pragma unroll(2) #pragma block_loop(10) for (i = 0; i < N; ++i) { } This is not allowed since the unroll directives are conflicting with each other.
例 4 - ブロックされたループに指定された矛盾するアンロール・ディレクティブ
#pragma block_loop(10) #pragma unroll(5) #pragma unroll(10) for (i = 0; i < N; ++i) { } This is not allowed since there are two different unrolling factors specified for the same loop, and therefore the diretives are conflicting.
関連情報