我们对 nvcc 的#pragma unroll 的“强度”了解多少?
Posted
技术标签:
【中文标题】我们对 nvcc 的#pragma unroll 的“强度”了解多少?【英文标题】:What do we know about the "strength" of nvcc's #pragma unroll? 【发布时间】:2017-07-20 03:06:48 【问题描述】:遇到#pragma unroll
指令时,我们对nvcc的展开能力了解多少?它有多复杂?有没有人尝试过越来越复杂的循环结构来看看它放弃了什么?
例如,
#pragma unroll
for(int i = 0; i < constexpr_value; i++) foo(i);
肯定会展开(达到相当大的行程计数,请参阅this answer)。怎么样:
#pragma unroll
for(int i = 0; i < runtime_variable_value and i < constexpr_value; i++)
foo(i);
这里不知道循环行程计数,但它有一个恒定的上限,并且可以执行循环的完全展开,并带有一些条件跳转。
然后呢:
template <typename T>
constexpr T simple_min(const T& x, const T& y) return x < y ? x : y;
#pragma unroll
for(int i = 0; i < simple_min(runtime_variable_value, constexpr_value); i++)
foo(i);
哪个应该编译成和上面一样的东西?
注意:如果您打算回答“进行自己的实验”,那么 - 我打算这样做,至少在我的示例中,如果没有人知道一般答案,请查看 PTX ,在这种情况下,我将部分回答这个问题。但我更喜欢更权威的、基于更广泛经验的东西。
【问题讨论】:
这在编程指南中有非常清楚的描述 @talonmies:实际上,这不是...查看我对实际行程计数与行程计数上限的编辑。 【参考方案1】:展开的规则非常简单——如果编译器不能将循环次数推导出为一个整数常量值,它就不会自动展开循环。在这种情况下,它还会发出警告通知您。
如果您的代码具有非恒定循环行程计数,您仍然可以通过在 unroll pragma 后添加一个值大于 1 的整型常量表达式来强制编译器展开(即 #pragma unroll 8
)
所有这些都在documentation 的相关部分中进行了非常清楚的讨论。
【讨论】:
以上是关于我们对 nvcc 的#pragma unroll 的“强度”了解多少?的主要内容,如果未能解决你的问题,请参考以下文章
确定 CUDA 中#pragma unroll N 的最佳值
在啥类型的循环中最好在 CUDA 中使用 #pragma unroll 指令?