2011-02-27 109 views
0

對於simpliflication,說我有這個結構:
someheader.h在CUDA中訪問一個struct成員?

typedef struct 
{ 
    float x 
}someStruct; 

在CUDA,如何將一個設備的功能訪問該結構的構件,如果該結構是由一個C++應用程序共享?

例如:

__global__ void stuff(someStruct *g) { 
    g[0].x = 0.4f; 
} 

是正確的方式做到這一點?它似乎沒有工作。

+0

你的問題不是很清楚......你究竟想知道什麼?對結構成員的訪問像往常一樣進行。 – 2011-02-27 20:32:28

+0

我已更新我的帖子。 – ninjaneer 2011-02-27 22:28:23

+0

是的,這是正確的做法。您的代碼中可能存在不同的問題。 – jmilloy 2011-02-28 05:30:11

回答

1

結構本身是一個抽象的實體,在主機或設備端沒有物理表示。

設備端對象的內存佈局與主機端完全相同(如果這就是您真正要求的),所以您可以安全地將大型結構對象從主機複製到設備,反之亦然。

訪問對象的成員只不過是在編譯時計算正確的偏移量並在運行時將其添加到對象指針(this)中。 CUDA完全有能力做到這一點。

someStruct.x=2將轉化爲這樣的彙編語言:

mov [someStruct]+0, 2 

其中0是你的結構內部成員x的偏移。

更新:

主機和存儲設備完成不同的(一個是在你的RAM,另外對你的GPU)。沒有什麼是共享的,一切都必須來回發送(這可能會非常耗時)。使用CudaMemcpy函數來複制數據。

+0

這裏沒有指針...... – 2011-02-27 20:35:51

+0

每個變量都有它的地址,因此你可以有一個指向它的指針。 – CygnusX1 2011-02-27 20:45:45

+0

它似乎並沒有工作。我試過了,它沒有正確地複製回主機。 – ninjaneer 2011-02-27 22:28:48

1

您需要將結構數組傳送到GPU。 例如訪問內核內部漂浮物的數組,你需要做以下

__global__ static void myKernel(float *val) 
{ 
val[0] = 0.4f; 
} 

int main() 
{ 
... 
cudaMemcpy(d_Val, h_Val, n * sizeof(float), cudaMemcpyHostToDevice); 
... 
} 

當然,這是基本常識。你可以用任何數據類型替換float並獲得相同的行爲。結構只是用戶定義的數據類型。

這與發送單個浮點數(因此是單個結構)不同,因爲所有對內核的輸入在運行時(取決於卡)從GPU的哪個位置被推入GPU內存系統的某個部分訪問這些值。所以如果輸入是一個結構體,當內核嘗試訪問它時,整個結構體駐留在GPU上。但是如果你發送一個指向在主機上生成的結構體的指針,那麼GPU就具有指針的值而不是實際的數據。