2011-02-19 103 views
1


在我的cuda代碼中,如果我增加blocksizeX,blocksizeY它實際上需要更多時間[因此,我以1x1運行它]另外還有一大塊執行時間(例如,9箇中的7個s)只是通過調用內核來實現的。事實上,我很驚訝即使我將整個內核註釋掉,時間也幾乎是一樣的。有什麼建議在哪裏以及如何進行優化?增加塊大小會降低性能

P.S.我已經用我的實際代碼編輯了這篇文章。我對圖像進行了下采樣,因此每4個相鄰像素(例如,對於例如1,2行和1,2行)給出一個輸出像素。我得到一個有效的bw。 5GB/s,理論最大值爲86.4 GB/s。我使用的時間是在調用內核和指令並調用一個空內核方面的差異。 我現在看起來很糟糕,但我無法弄清楚我做錯了什麼。

__global__ void streamkernel(int *r_d,int *g_d,int *b_d,int height ,int width,int *f_r,int *f_g,int *f_b){ 


    int id=blockIdx.x * blockDim.x*blockDim.y+ threadIdx.y*blockDim.x+threadIdx.x+blockIdx.y*gridDim.x*blockDim.x*blockDim.y; 
    int number=2*(id%(width/2))+(id/(width/2))*width*2; 

    if (id<height*width/4) 
    { 

     f_r[id]=(r_d[number]+r_d[number+1];+r_d[number+width];+r_d[number+width+1];)/4;        
     f_g[id]=(g_d[number]+g_d[number+1]+g_d[number+width]+g_d[number+width+1])/4;    
     f_b[id]=(g_d[number]+g_d[number+1]+g_d[number+width]+g_d[number+width+1];)/4; 
    } 


    } 
+0

謝謝!但我做了谷歌,並做了一些功課,然後發佈在堆棧溢出。 – Manish 2011-02-19 06:41:07

+0

@Nick:[LMGTFY網址不允許出於某種原因](http://meta.stackexchange.com/questions/15650/ban-lmgtfy-let-me-google-that-for-you-links)。你會知道,如果你沒有試圖用tinyurl來混淆它,這也是*強烈不鼓勵。我喜歡知道我被鏈接到哪裏。 – 2011-02-19 07:02:53

+0

@Manish - 我想幫助你,但是你對前面提到的關於cuda的兩個問題沒有選擇正確的答案。如果你給我們更多的激勵,這將有所幫助。 – jmilloy 2011-02-19 07:38:11

回答

0

您忘記了一個多處理器可以同時執行多達8個塊的事實,並且當時達到最高性能。然而,有許多因素限制塊中的可以同時存在(不完全列表)的數量:

  • 每個多處理器共享存儲器的最大量限制如果#blocks *每塊共享存儲器將是塊的數量>總共享內存。
  • 如果#blocks * #threads/block>> max total #threads,則每個多處理器的最大線程數限制塊的數量。
  • ...

你應該嘗試找到引起正好是8塊要在一個多處理器上運行內核執行配置。即使入住率=/= 1.0,這幾乎總是會產生最高的性能!從這一點開始,您可以嘗試迭代地進行更改,以減少每個MP執行塊的數量,但是因此會增加內核的佔用量並查看性能是否提高。

nvidia occupancy calculator(excel sheet)會有很大的幫助。

2

嘗試在CUDA SDK示例中查找矩陣乘法示例以瞭解如何使用共享內存。

當前內核的問題是,它爲每3個添加和1個分區寫入4個全局內存讀取和1個全局內存寫入。每次全局內存訪問大約需要400個週期。這意味着你花費絕大多數時間進行內存訪問(GPU不好),而不是計算(GPU優秀)。

共享內存有效地允許您緩存這個以便分期付款,您可以在每個像素上進行大約1次讀取和1次寫入,以進行3次添加和1次分割。對於CGMA比率(計算到全球存儲器訪問比率,GPU計算的聖盃),這仍然沒那麼好。總的來說,我認爲對於這樣一個簡單的內核來說,考慮到通過PCI-E總線傳輸數據的開銷,CPU實現可能會更快。