2012-07-02 26 views
0

我作爲結構內部的推力:: device_vector

struct Point 
{ 
int x; 
int y; 
float val; 
} 

我打算用這個結構來表示稀疏矩陣的結構(我CUSPARSE,牙尖的認識 但我只打算使用 推力進行一些測試)並使用推力算法執行操作。

從我在CUDA編程教程中學到的東西,總是建議使用 數組結構而不是結構數組來更好地結合內存。

如果是這種情況,那麼如果使用上述結構在device_vector中存儲非零值(以數百萬的數量級),該device_vector在處理推力算法時會使用GPU內部的未對齊內存訪問嗎?

我問這個,因爲我可能需要訪問此 device_vector中的不規則步幅,並通過傳遞多個 函數對象來執行算法操作。

它會像定製內核一樣高效地運行在數組結構上嗎?

謝謝。

回答

4

NVIDIA CUDA設備可以有效地訪問4,8和16字節的結構,從而有效地採用合併內存訪問模式。爲此,CUDA頭部定義了您可以使用的結構int2int4float2float4等。他們被定義爲具有有效的對準,而不是您的自定義Point結構上,我建議在經使用

typedef int2 Point; 

當所有的內存訪問這些小結構的陣列連續跨線程(如合併),所有數據在每個struct元素由讀/寫它的線程使用,那麼這種類型的AOS訪問非常有效。實際上,使用這樣的向量結構通常會導致比標量數據訪問更高的內存吞吐量,這是由於在運行中增加了內存交易。

Thrust提供了zip_iterator,專門用於在SOA數據上操作的便利性和(編碼)效率,就好像它是AOS數據一樣。因此,雖然小型結構在直接CUDA C++中是高效的,但在使用Thrust時,您可能會選擇對每個結構成員使用單獨的device_vector,並在調用transform和其他推力算法之前使用zip_iterator將它們一起壓縮。 Thrust示例代碼中包含這些示例。

+1

我同意所有這些,特別是對於自定義的kernes,但是對於推力的具體使用,我懷疑只需使用三個設備矢量(或者可以是座標的矢量/矢量/數據矢量)將會更簡單和更容易。 – talonmies

+1

對不起,我錯過了關於Thrust的部分。編輯我的答案以涵蓋該案例。請注意,如果您受到帶寬限制,則使用小型結構,然後編寫自定義函子以在Thrust中對其進行操作可能仍然更有效。 – harrism

+0

@harrism ...謝謝我最終使用__align__運算符,同時定義我的struct.Will是否有效,如果我在推力內使用它? – Recker