2013-04-05 114 views
0

這裏存儲數據性能低是我的問題,以加快我的項目,我要保存的內部內核生成到共享內存的值,但是,我發現它需要這麼長時間來保存該值。如果我刪除「THIS LINE」(見下面的代碼),即去掉「THIS LINE」,速度非常快,以保存值(100次加速!)。CUDA,在共享memroy

extern __shared__ int sh_try[]; 

__global__ void xxxKernel (...) 
{ 
    float v, e0, e1; 
    float t; 
    int count(0); 
    for (...) 
    { 
    v = fetchTexture(); 
    e0 = fetchTexture(); 
    e1 = fetchTexture(); 
    t = someDeviceFunction(v, e0, e1); 
    if (t>0.0 && t < 1.0) <========== <THIS LINE> 
     count++; 
    } 
    sh_try[threadIdx.x] = count; 
} 

main() 
{ 
    sth.. 
    START TIMING: 

    xxxKernel<<<gridDim.x, BlockDim.x, BlockDim.x*sizeof(int)>>> (...); 

    cudaDeviceSynchronize(); 

    END TIMING. 
    sth... 
} 

爲了解決這個問題,我簡化了我的代碼,只是將數據保存到共享內存中。並停下來。因爲我知道共享內存。是最有效的成員。除了註冊,我不知道這個高延遲是正常還是我做錯了。請給我一些建議!謝謝你們提前!

trudi

更新: 如果我替換共享全球MEM內存,它需要幾乎在同一時間,爲33ms無「THIS LINE」,它297ms。將數據保存到全局mem是否正常?需要與共享內存相同的時間?這也是「編譯器優化」的一部分嗎?

我也檢查了其他類似的問題,也就是說,即將數據保存到共享內存或沒有,這可能是由編譯器優化造成的巨大時間差距,因爲它是沒有意義的計算數據,但不保存它們,所以編譯器只是'刪除'那些毫無意義的代碼。

我不知道我是否共享相同的原因,因爲行改變了遊戲規則是一個假設 - 「THIS LINE」,當我評論它,變量「計數」增加每次迭代,當我取消它在t有意義時增加。

任何想法?請...

+2

當更改單行代碼時看到像這樣的大速度差異時,很可能是因爲編譯器能夠優化出大塊代碼。由於您的內核僅將數據存儲在共享內存中,因此它沒有任何用處。編譯器可以檢測到這一點,並用一個空內核來替代它。您可以通過使用'nvcc -ptx mycode.cu'查看代碼輸出來查看這兩種情況的區別。 – 2013-04-05 07:48:13

+1

使用「@name」通知評論者。 ptx文件在某種程度上是可讀的。要檢查的主要問題是你的函數的主體。它應該以'.entry _Z6xxxKernelILi2EEvPj(){'開始。之後,彙編代碼如下所示。 – stuhlo 2013-04-05 09:40:48

+0

@stuhlo,謝謝你的回覆。也許我應該先弄清楚如何用nvcc -ptx編譯。我得到一個錯誤'無法找到cutil_inline.h'任何想法? – trudiQ 2013-04-05 13:13:45

回答

1

通常情況下,當大的性能變化被看作是比較小的代碼更改(如添加或刪除一行代碼在內核)的結果,性能變化不是由於實際性能的影響該行代碼,但都是由於編譯器做出不同的優化決策,這可能會導致批發添加或在你的內核的機器代碼的缺失。

一個相對簡單的方法來幫助確認這是看生成的機器代碼。例如,如果所生成的機器代碼的大小顯着改變由於源代碼的單個行的添加或缺失,也可能是編譯器作出極大地影響該代碼的優化決定的情況。

雖然它不是機器代碼,但爲了達到這些目的,合理的代理是查看生成的PTX代碼,這是編譯器創建的中間代碼。

可以產生通過簡單地將-ptx切換到您的編譯命令PTX:

nvcc -ptx mycode.cu 

這將生成一個名爲mycode.ptx您可以檢查這些文件。當然,如果你的常規編譯命令需要額外的開關(例如-I/path/to/include/files),那麼這個命令可能需要那些相同的開關。 nvccmanual提供了有關代碼生成選項的更多信息,並且有一個PTX manual可幫助您瞭解PTX,但您可能僅基於生成的PTX的大小就能得出一個大概的想法(例如,.ptx文件中的行數)。