2017-02-28 64 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的相關章節中進行了非常清晰的討論。