2013-02-24 30 views
1

我需要Cuda GLOBAL內存的一些幫助。在我的項目中,我必須聲明全局數組,以避免在每次內核調用時發送此數組。內核調用示例之前的CUDA全局數組聲明和初始化

編輯:

我的應用程序可以調用內核的1000倍以上,並在每一個電話我送他的大小比[1000×1000]以上的陣列,所以我認爲這是花更多的時間,這就是爲什麼我的應用運行緩慢。所以,我需要聲明的GPU全局數組,所以我的問題是

如何聲明全局數組

如何內核調用前初始化從CPU全球陣列提前

謝謝

+1

共享內存只有塊範圍。在內核運行之前,您不能分配和填充共享內存。 – talonmies 2013-02-24 13:56:16

+0

也許我需要全球記憶?我可以爲每個塊,線程聲明全局數組嗎? – 2013-02-24 14:05:33

+0

是的,你可以,但它不能解決任何問題,請嘗試將數據保存在全局內存中,並在調用內核時,將其複製到內核中的共享內存中。但如果您只使用一次數據或者只需要線程中的單個數據,則這樣做不起作用。那麼你最好使用一個普通變量並將其分配給它。這樣編譯器會自動將該變量轉換爲註冊。 – 2013-02-24 15:30:28

回答

3

你編輯的問題很混亂,因爲你說你要發送你的內核一個大小爲1000 x 1000的數組,但是你想知道如何使用全局數組來做到這一點。我知道將這麼多數據發送到內核的唯一方法是使用全局數組,因此您可能已經在全局內存中使用數組執行此操作。

儘管如此,有2種方法,至少,來創建和初始化在全局存儲器陣列:

1.statically,使用__device__cudaMemcpyToSymbol,例如:

#define SIZE 100 
__device__ int A[SIZE]; 
... 
int main(){ 
    int myA[SIZE]; 
    for (int i=0; i< SIZE; i++) myA[i] = 5; 
    cudaMemcpyToSymbol(A, myA, SIZE*sizeof(int)); 
    ... 
    (kernel calls, etc.) 
} 

device variable referencecudaMemcpyToSymbol reference

2.dynamically,使用cudaMalloccudaMemcpy

#define SIZE 100 
... 
int main(){ 
    int myA[SIZE]; 
    int *A; 
    for (int i=0; i< SIZE; i++) myA[i] = 5; 
    cudaMalloc((void **)&A, SIZE*sizeof(int)); 
    cudaMemcpy(A, myA, SIZE*sizeof(int), cudaMemcpyHostToDevice); 
    ... 
    (kernel calls, etc.) 
} 

cudaMalloc referencecudaMemcpy reference

爲清楚起見,我省略error checking,你應該對所有CUDA調用和內核調用做。

+0

太好了,謝謝:) – 2013-02-25 19:37:55

0

如果我很好地理解了這個問題,這個問題還不清楚,你想在全部內核調用中使用全局數組並將其發送到設備。這不好實踐導致高延遲,因爲在每個內核調用中,您需要將數據傳輸到設備。根據我的經驗,這種做法導致負面加速。

最佳方式是使用我所說的觸發器技術。你這樣做的方式是:

  1. 聲明設備中的兩個數組。 d_arr1d_arr2
  2. 將數據host -> device複製到其中一個數組中。
  3. 作爲內核參數傳遞指向d_arr1d_arr2
  4. 將數據處理到內核中。
  5. 在隨之而來的內核調用你交換你逝去的指針作爲參數

這樣你可以避免傳送數據的每個內核調用。您只能在主循環的開始和結束時進行傳輸。

int a, even =0; 
for(a=0;a<1000;a++) 
{ 
    if (even % 2 ==0) 
    //call to the kernel(pointer_a, pointer_b) 
    else 
    //call to the kernel(pointer_b, pointer_a) 
}