#pragma unroll 和 #pragma nounroll

适用的调用

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

请参阅 -qunroll (-funroll-loop) , -qunroll=yes (-funroll-all-loop)

用途

控制循环展开以提高性能。

语法

读取语法图跳过可视语法图#pragma nounrollunroll(n)

参数

n
指示编译器按因子 n 来展开循环。 换句话说,将复制循环的主体,以创建 n 个副本(包括原始主体),迭代次数按因子 1/n 减小。 n 的值必须是正整数。
指定 #pragma unroll(1) 将禁用循环展开,与指定 #pragma nounroll 等效。

使用量

在一个循环上只能指定一个编译指示。 编译指示必须紧跟在循环或 #pragma block_loop 伪指令之前出现,才能 生效

编译指示只影响位于其后面的循环。 如果 所需 循环的解滚策略与 -funroll-loops (-qunroll) 选项的解滚策略不同,那么内部嵌套循环需要 #pragma unroll 伪指令在其前面。

#pragma unroll#pragma nounroll 伪指令只能在 for loop#pragma block_loop 伪指令上使用。 它们不能应用于 do whilewhile 循环。

循环结构必须满足以下条件:
  • 必须只有一个循环计数器变量、该变量的一个增量点和一个终止变量。 在循环嵌套中的任何位置都不能改变这些内容。
  • 循环不能有多个入口点和出口点。 循环终止必须是退出循环的唯一方法。
  • 循环中的依赖关系不能是“回顾”。 例如,诸如 A[i][j] = A[i -1][j + 1] + 4 之类的语句不得出现在循环中。

示例

在以下示例中,第一个 for 循环上的 #pragma unroll (3) 伪指令要求编译器复制循环的主体三次。 第二个 for 循环上的 #pragma unroll 允许编译器决定是否执行取消滚动。
#pragma unroll(3)
for( i=0;i < n; i++)
{
      a[i] = b[i] * c[i];
}

#pragma unroll
for( j=0;j < n; j++)
{
      a[j] = b[j] * c[j];

}
在此示例中,第一个 #pragma unroll(3) 伪指令导致:
i=0;
if (i>n-2) goto remainder;
for (; i<n-2; i+=3) { 
  a[i]=b[i] * c[i];
  a[i+1]=b[i+1] * c[i+1]; 
  a[i+2]=b[i+2] * c[i+2]; 
} 
if (i<n) { 
  remainder: 
  for (; i<n; i++) { 
    a[i]=b[i] * c[i]; 
  } 
}