我们对 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 指令?

使用 CreateProcess 调用 nvcc.exe

#pragma mark指令

为啥 NVCC 对 constexpr 比非 constexpr 主机函数更严格?

#pragma pack(push) 和#pragma pack(pop) 以及#pragma pack()