如果行程计数不恒定,为啥我的#pragma-unrolled 循环的性能会下降?

Posted

技术标签:

【中文标题】如果行程计数不恒定,为啥我的#pragma-unrolled 循环的性能会下降?【英文标题】:Why does the performance of my #pragma-unrolled loop degrade if the trip count is not constant?如果行程计数不恒定,为什么我的#pragma-unrolled 循环的性能会下降? 【发布时间】:2011-07-26 14:55:41 【问题描述】:

我有以下代码使用循环展开:

#pragma unroll
for (int i=0;i<n;i++)

    ....

如果 n 是一个已定义的常量,那么一切正常。但是,如果 n 是一个变量,则性能会显着降低。我注意到大约 3 次指令被发出和执行。我想我正在寻找一种在运行时进行循环展开的方法,这可能是不可行的。

【问题讨论】:

【参考方案1】:

CUDA 是一种编译语言。循环展开是一种编译器优化。运行时循环展开意味着某种运行时解释器或动态代码生成。这显然不可能发生。

unrolled 案例执行的指令与原始循环一样多或更多是有道理的,因为编译器将用循环内容的重复来替换循环。如果展开的 case 执行 less 指令,这意味着编译器正在预先计算部分或全部循环内容并用常量结果替换代码。

这完全取决于循环中包含的内容。

【讨论】:

更基本的,常量在编译时是已知的,变量不是。 即使在编译时不知道循环的行程计数时,open64 也可以并且确实会发生循环展开,并且这样做通常是一种优化,因为它可以增加指令级并行度。这里的“谜团”是非恒定行程计数情况下的指令量,这必须是由于代码替换而不是恒定行程情况下的循环展开。 我同意你的代码替换。我想我错过了一个假设,即循环中的语句不是独立的。正如你所说,这完全取决于循环中的内容。

以上是关于如果行程计数不恒定,为啥我的#pragma-unrolled 循环的性能会下降?的主要内容,如果未能解决你的问题,请参考以下文章

英特尔自动矢量化行程计数解释?

使用 Impala 获取连续行程的计数

为啥 Postgres 不接受我的计数列?

为啥我的计数排序算法根本不排序?

为啥 CUDA 内存复制速度表现得像这样,一些恒定的驱动程序开销?

为啥我的 ASP.NET MVC 多实例性能计数器不起作用