#pragma block_loop

适用的调用

表 1. 接受给定编译指示的调用
编译指示 (pragma) xlc (编译 C) xlC (编译 C++) xlclang(编译 C) xlclang++(编译 C++)
#pragma block_loop    
注: 此表中仅列出典型调用。 对于所有基本调用及其等效特殊调用,您可以参阅 编译器调用的完整列表

类别

优化和调整

用途

使用特定于作用域的标识来标记块。

语法

读取语法图跳过可视语法图#pragmablock_loop( 表达式, ,名称 )

参数

expression
表示迭代组大小的整数表达式。
名称
作用域限定单元中唯一的标识。 如果未指定 name,那么在 #pragma block_loop 伪指令之后的第一个 for 循环或循环上将发生分块。

使用量

要使循环阻塞发生, #pragma block_loop 伪指令必须在 for 循环之前。

如果对阻塞循环指定 #pragma unroll#pragma unrollandfuse#pragma stream_unroll ,那么如果实际创建了阻塞循环,那么将分别对阻塞循环进行解滚,解滚和融合或流解滚。 否则,此伪指令无效。

如果为阻塞循环指定 #pragma unrollandfuse#pragma unroll#pragma stream_unroll 伪指令,那么在创建阻塞循环之后,该伪指令将应用于阻塞循环。 如果未创建阻塞循环,那么此伪指令将应用于用于阻塞的循环,就像未指定相应的 #pragma block_loop 伪指令一样。

不得多次指定 #pragma block_loop ,也不得将该伪指令与 #pragma nounroll#pragma unroll#pragma nounrollandfuse#pragma unrollandfuse#pragma stream_unroll 伪指令组合到同一 for 循环中。 此外,不应将多个 #pragma unroll 伪指令应用于单个块循环伪指令。

始终先完成所有 #pragma block_loop 伪指令的处理,然后再执行由任何解滚伪指令指示的任何解滚

示例

以下两个示例显示了如何使用 #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 for loop tiling for 多级内存层次结构:
 #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) {
   }
在这种情况下,如果忽略 block loop 伪指令,那么 unroll 伪指令没有任何作用。
以下示例显示了如何使用 #pragma unroll#pragma block_loop 来取消滚动阻塞的循环。
 #pragma block_loop(10)
 #pragma unroll(2)
   for (i = 0; i < N; ++i) {
   }
在这种情况下,如果忽略 block loop 伪指令,那么 unblocked 循环仍会进行解滚。 如果发生分块,那么会将 unroll 伪指令应用于分块循环。
以下示例显示了该伪指令的无效用法。 第一个示例显示在未定义的循环标识上使用的 #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++)
   {
     ...
   }
由于 unroll 伪指令相互冲突,因此以下示例无效:
 #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) {
   }

相关信息