2017-02-28 23 views
1

当遇到#pragma unroll指令时,我们知道nvcc的展开功能是什么?它有多复杂?有没有人尝试过越来越复杂的循环结构,看看它放弃了什么?我们知道nvcc的#pragma展开的“优势”是什么?

例如,

#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如果没有人知道一般的答案已经,在这种情况下,我会部分回答这个问题。但我更喜欢一些更权威的东西,并以更广泛的经验为基础。

+0

这在编程指南 – talonmies

+0

@talonmies中有非常清楚的描述:实际上,它不是......查看我编辑的实际行程计数与行程计数的上限。 – einpoklum

回答

2

展开规则非常简单 - 如果编译器无法将循环行程计数推断为整型常量值,则不会自动展开循环。在这种情况下,它也会发出警告通知你。

如果有具有非恒定循环行程计数代码,则仍然可以通过用值加法整数表达式大于一的UNROLL编译指示后到强制编译器展开(即#pragma unroll 8

所有这些都在documentation的相关章节中进行了非常清晰的讨论。

相关问题