#pragma block_loop

説明

スコープ固有の 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 ループに先行している必要があります。

ブロッキング・ループに unrollunroll_and_fuse、または stream_unroll ディレクティブを指定すると、ブロッキング・ループが実際に作成された場合、ブロッキング・ループがそれぞれアンロール、アンロールおよびフューズ、またはストリーム・アンロールされます。それ以外の場合、このディレクティブは何の効果もありません。

ブロックされたループに unroll_and_fuse または stream_unroll ディレクティブを指定すると、ディレクティブはブロッキング・ループの作成後に、ブロックされたループに適用されます。ブロッキング・ループが作成されないと、対応する block_loop ディレクティブが指定されていないかのように、このディレクティブがブロッキングを意図したループに適用されます。

#pragma block_loop を複数回指定したり、同じ for ループに対してこのディレクティブを nounrollunrollnounrollandfuseunrollandfuse、または 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.

関連情報