#pragma block_loop

カテゴリー

最適化およびチューニング

目的

スコープ固有の ID を使用してブロックにマークを付ける。

構文

構文図を読む構文図をスキップする
                                            .-,----.      
                                            V      |      
>>-#--pragma--block_loop--(--expression--,----name-+--)--------><

パラメーター

expression
繰り返しグループのサイズを表す整数式です。
name
スコープ単位内で固有の ID です。name を指定しないと、最初の for ループ、または #pragma block_loop ディレクティブの後のループでブロッキングが発生します。

使用法

ループ・ブロッキングが発生するには、#pragma block_loop ディレクティブが for ループに先行している必要があります。

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

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

同じ for ループに対して #pragma block_loop を複数回指定したり、このディレクティブを #pragma nounroll#pragma unroll#pragma nounrollandfuse#pragma unrollandfuse、または #pragma stream_unroll ディレクティブと結合しないでください。また、単一のブロック・ループ・ディレクティブに複数の #pragma unroll ディレクティブを適用しないでください。

すべての #pragma block_loop ディレクティブの処理は常に、いずれかの unroll ディレクティブによって示されるアンロールの実行前に完了します。

以下の 2 つの例では、ループ・タイルの #pragma block_loop および #pragma loop_id の使用方法を示しています。
#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++)
      {
         ...
      }
    }
  }
#pragma block_loop(50, mymainloop)
#pragma block_loop(20, myfirstloop, mysecondloop)
#pragma loopid(mymainloop)
       for (i=0; i < n; n++)
       {
#pragma loopid(myfirstloop)
              for (j=0; j < m; j++)
              {
#pragma loopid(mysecondloop)
                     for (k=0; k < m; k++)
                     {
                            ...
                     }
              }
       }
以下の例では、ループ交換の #pragma block_loop および #pragma loop_id の使用方法を示しています。
       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++)
                            {
                                   ...
                            }
                     }
              }
       }
以下の例では、マルチ・レベルのメモリー階層用のループ・タイルの #pragma block_loop および #pragma loop_id の使用方法を示しています。
 #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++)
         {
           ...
         }
       }
     }
   }
以下の例では、#pragma unrollandfuse および #pragma block_loop を使用して、ブロッキング・ループをアンロールおよびヒューズしています。
#pragma unrollandfuse
#pragma block_loop(10)
   for (i = 0; i < N; ++i) {
   }
この場合、ブロック・ループ・ディレクティブが無視されると、アンロール・ディレクティブは何の効果も及ぼしません。
以下の例では、ブロックされたループをアンロールするための #pragma unroll および #pragma block_loop の使用法を示しています。
 #pragma block_loop(10)
 #pragma unroll(2)
   for (i = 0; i < N; ++i) {
   }
この場合、ブロック・ループ・ディレクティブが無視されても、非ブロック化されたループはアンロールされます。ブロッキングが発生した場合は、アンロール・ディレクティブはブロックされたループに適用されます。
以下の例は、ディレクティブの無効な使用方法を示しています。最初の例は、未定義のループ ID で使用された #pragma block_loop を示しています。
 #pragma block_loop(50, myloop)
   for (i=0; i < n; i++)
   {
   }
myloop は、ネスト内になく定義されない場合があるため、参照できません。
以下の例では、myloop は、同じループ・ネスト内にないため参照できません。
   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++)
   {
     ...
   }
以下の例は無効です。これは、アンロール・ディレクティブがお互いに矛盾するためです。
 #pragma unrollandfuse(5)
 #pragma unroll(2)
   #pragma block_loop(10)
              for (i = 0; i < N; ++i) {
          }
 #pragma block_loop(10)
 #pragma unroll(5)
 #pragma unroll(10)
   for (i = 0; i < N; ++i) {
   }

関連情報