2014-11-21 75 views
0

我在每個方向創建了一個網格(N,N)單元,我想檢查哪些點對應哪個單元,這很容易,但是,有一些點可以離開網格,我希望它把它放到一個單元格中。哪種操作對性能,最小/最大或模數的影響最小?

這些都是在GPU中完成的,所以我的問題是關於什麼纔是映射點到有效單元格的最佳操作?

使用max(0,min(N,cell.x))的第一個選項我相信會引入內核的分歧。第二種選擇是使用模數(cell.x%N),我認爲這是GPU中非常昂貴的操作。

我怎樣才能決定使用哪一個?

+0

你知道N嗎?例如,用兩個冪的modtros很便宜。 – Jez 2014-11-21 14:42:49

+0

我在想這個,但我想在某些情況下,這意味着增加所需的內存是正確的?但是,呃...網格不應該那麼大,所以它可能是一個選擇。 – BRabbit27 2014-11-21 14:49:30

+1

'使用max(0,min(N,cell.x))的第一個選項,我相信它會在內核中引入分歧「爲什麼你認爲這會引入分歧?這些函數應該映射到非常高效的無分支程序集,例如'min.s32'和'max.s32'。那裏沒有分歧。 – 2014-11-21 15:04:07

回答

2

GPU具有整數min()max()的硬件指令。如果使用cuobjdump --dump-sass從nvcc編譯的可執行文件中轉儲機器代碼,則可以識別這些指令,例如,它們被稱爲IMNMXVMNMX(「mnmx」代表「最小值或最大值」,兩個操作之間的選擇是通過謂詞)。

對於N這是一個編譯時常量冪的兩倍,模運算應該映射到一個單指令LOP.AND。對於其他編譯時常量值N,發出一個小指令序列,通常涉及整數乘法和移位。對於變量N,即在運行時確定,模運算將基本上需要至少15條左右指令的全整數除法。

因此,除了編譯時常量N是2的冪的情況之外,從性能角度看,使用min()max()進行的鉗位似乎優於基於模的解決方案。但是,除非您的代碼頻繁執行此操作並受計算吞吐量限制,否則內核級別的性能差異可能很小或可能不存在(例如,如果代碼是內存帶寬受限的)。