2012-10-04 72 views
1

我目前正在編寫OpenCL內核(但​​我認爲在CUDA中將是相同的),並且目前我嘗試針對NVidia GPU進行優化。OpenCL和CUDA註冊使用優化

我目前在我的內核使用63個寄存器,這個內核是非常大的,所以它使用所有GPU的寄存器。我正在尋找一些方法來:

1)查看哪些變量是寄存器,然後將它們在全局內存(因爲如果我沒有足夠的寄存器似乎編譯器保存在全局內存中的變量)。

2)是否有可指定哪個變量是更重要的(或應是在寄存器中)的方法。因爲我使用了一些存在但較少使用的變量。一種優先考慮的方法?

當我們已經使用所有的寄存器時,還有其他優化策略嗎?

BTW:我也嘗試讀取PTX代碼並搜索所有「.reg」關鍵字,但問題是PTX不可讀,我不知道哪個寄存器用於我的代碼中的哪個變量。我一直沒有找到任何方法來獲得相應的答案!

感謝

回答

2

看到哪些變量是在寄存器,然後將它們在全球 內存

爲此,我不知道如何檢查的方式,但是

是有沒有辦法來指定哪些變量是更重要的

當我看到我有溢出寄存器(由於缺少它們或當我需要在本地變量中使用動態索引時,這是不好的)時,我使用的一個技巧是明確地存儲那些,我認爲並不那麼關鍵,存入本地內存(在CUDA中稱爲「共享」)

例如前:

uint16 somedata; 

後:

__local uint16 somedata[WG_SIZE]; // or __local uint someadata[16]; 

,但要注意,如果你的本地內存使用量會大大增加你冒着有罰,因爲機上的波陣面的數量會更少(即你可能會比較低佔用)

希望這會有所幫助。

+0

__local uint16 somedata意味着組中的所有線程將看到相同的變量而不是私人副本,因此它會導致不同的行爲。 –

+0

是的,你是對的,我犯了一個錯字,實際上我應該寫__local uint16 somedata [WG_SIZE];我會糾正它。 – alariq

3

(1)這就是所謂的寄存器溢出。除了檢查SASS組件外,我不認爲有辦法找出哪些變量會溢出。首先將OpenCL編譯爲PTX,該PTX是具有無限數量寄存器(無溢出)的虛擬機。有關更多信息,請參閱NVIDIA演示文稿Local Memory and Register Spilling

(2)你可以嘗試宣告你不想保持寄存器變量時使用volatile關鍵字。 volatile將強制編譯器將變量推送到內存,而不是將其攜帶在操作之間的寄存器中。

+3

'volatile'也阻止了很多優化,所以它不一定是勝利。 – tera

+0

volatile是個壞主意,因爲_every_ time使用了變量,所以會有讀取。而從全球記憶來看,這將是緩慢的。 –

1

在沒有看到代碼,一種方法嘗試「強制」使用寄存器可以在有限的範圍內使用本地副本。 也許只有一些變量可以在代碼的指定部分訪問。然後你可以在一個作用域中聲明新的變量並集中使用它們。沒有保證,但我知道它有時會有所幫助。

int a, b, d; 
double x,y; 

... 

{ 
    int ra = a;  // copy into new variables more likely to be kept in registers 
    double rx = x; 

    ... use rx and ra ... 

    a = ra; 
    b = rx;  // copy back. 
} 

... 
+0

非常感謝所有您的答案, 我也嘗試讀取PTX代碼並搜索所有「.reg」關鍵字,但問題是PTX不可讀,我不知道使用哪個寄存器我的代碼中的哪個變量。我一直沒有找到任何方法來獲得相應的答案! – Spectral

+0

看來,優化寄存器使用的最佳方式是使用{...}來定義範圍。我很驚訝,沒有任何幫助,編譯器無法做到這一點! – Spectral

+0

別的......在CUDA中,我們可以使用cudaDeviceSetCacheConfig方法來增加L1緩存的大小。是否有人知道是否有方法從OpenCL軟件中調用它,即使它不是真正的標準! – Spectral