-qunroll (-funroll-loops) 和 -qunroll=yes (-funroll-all-loops)
适用的调用
选项 | xlc (编译 C) | xlC (编译 C++) | xlclang(编译 C) | xlclang++(编译 C++) |
---|---|---|---|---|
-qunroll | ✓ | ✓ | ✓ | ✓ |
-funroll-loops, -funroll-all-loops | ✓ | ✓ |
注: 此表中仅列出典型调用。 对于所有基本调用及其等效特殊调用,您可以参阅 编译器调用的完整列表 。
类别
等效编译指示
xlc/xlC 和其他遗留的调用命令 | xlclang/xlclang + + 调用命令 |
---|---|
#pragma 选项 [no] unroll [= yes|no|auto|n] , #pragma unroll | 无 |
用途
控制循环展开以提高性能。
- -funroll-loops
- 指示编译器执行基本循环取消滚动。
- -funroll-all-loops
- 指示编译器搜索循环解滚的机会比使用 -funroll-loops执行的机会更多。 通常, -funroll-all-loops 比 -funroll-loops 处理更有可能增加编译时间或程序大小,但也可能提高应用程序的性能。
当 unroll 生效时,优化器确定并应用每个循环的最佳解滚因子; 在某些情况下,可以修改循环控制以避免不必要的分支。 编译器仍是是否取消循环的最终判优程序。
语法
缺省值
-funroll-loops 或者 -qunroll=auto
参数
以下子选项仅适用于 -qunroll :
- auto(仅选项)
- 指示编译器执行基本循环取消滚动。
- yes(仅选项)
- 指示编译器搜索循环解滚的机会比使用 auto执行的机会更多。 通常,此子选项比 auto 处理更有可能增加编译时间或程序大小,但也可能提高应用程序的性能。
- no(仅选项)
- 指示编译器不取消循环。
- n
- 指示编译器按因子 n 来展开循环。 换句话说,将复制循环的主体,以创建 n 个副本,迭代次数按因子 1/n 减小。 -qunroll=n 选项指定影响尚未具有 unroll pragma 的所有循环的全局取消卷因子。 n 的值必须是正整数。
指定不带任何子选项的 -qunroll 等同于 -qunroll=yes。
-qnounroll 等同于 -qunroll=no。
使用量

编译指示将覆盖指定循环的选项设置。 但是,即使为给定循环指定了 #pragma unroll ,编译器仍是循环是否被解压的最终判优程序。
在一个循环上只能指定一个编译指示。 编译指示必须紧跟在循环或 #pragma block_loop 伪指令之前出现,才能 生效 。
编译指示只影响位于其后面的循环。 内部嵌套循环需要 #pragma unroll 伪指令在其前面 (如果 想要 循环的解滚策略与通行选项的解滚策略不同)。
#pragma unroll 和 #pragma nounroll 伪指令只能在 for
loop 或 #pragma block_loop 伪指令上使用。 它们不能应用于 do while
和 while
循环。
循环结构必须满足以下条件:
- 必须只有一个循环计数器变量、该变量的一个增量点和一个终止变量。 在循环嵌套中的任何位置都不能改变这些内容。
- 循环不能有多个入口点和出口点。 循环终止必须是退出循环的唯一方法。
- 循环中的依赖关系不能是“回顾”。 例如,诸如
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];
}
}
