2013-07-04 45 views
0

上週我開始CUDA,因爲我必須將現有的C++程序轉換爲cuda以供我的研究。基本CUDA指針/數組內存分配和使用

這是CUDA by Example書中的一個基本示例,我向任何想學習CUDA的人推薦!

有人可以解釋如何用'dev_c'這是一個空指針分配GPU內存?

HANDLE_ERROR(cudaMalloc((void**)&dev_c, N * sizeof(int))); 

然後,調用函數「添加」,但對待*時不傳遞任何「dev_c」值C作爲全球功能的陣列,並從函數內寫呢?爲什麼當它沒有在任何地方定義爲數組時,這是可能的?

add<<<N,1>>>(dev_a, dev_b, dev_c); 

最後,在執行以下相加操作時,c [0],c [1]等術語到底會保存嗎?

c[tid] = a[tid] + b[tid]; 

我希望我能很好的解釋自己,但隨時可以問任何後續問題。新的C以及CUDA所以是很好的:d以下

整個代碼:

#include "book.h" 

#define N 1000 

__global__ void add(int *a, int *b, int *c) { 
    int tid = blockIdx.x; // this thread handles the data at its thread id 
    if (tid < N) 
     c[tid] = a[tid] + b[tid]; 
} 

int main(void) { 
    int a[N], b[N], c[N]; 
    int *dev_a, *dev_b, *dev_c; 

    // allocate the memory on the GPU 
    HANDLE_ERROR(cudaMalloc((void**)&dev_a, N * sizeof(int))); 
    HANDLE_ERROR(cudaMalloc((void**)&dev_b, N * sizeof(int))); 
    HANDLE_ERROR(cudaMalloc((void**)&dev_c, N * sizeof(int))); 

    // fill the arrays 'a' and 'b' on the CPU 
    for (int i=0; i<N; i++) { 
     a[i] = -i; 
     b[i] = i * i; 
    } 

    // copy the arrays 'a' and 'b' to the GPU 
    HANDLE_ERROR(cudaMemcpy(dev_a, a, N * sizeof(int), 
           cudaMemcpyHostToDevice)); 
    HANDLE_ERROR(cudaMemcpy(dev_b, b, N * sizeof(int), 
           cudaMemcpyHostToDevice)); 

    add<<<N,1>>>(dev_a, dev_b, dev_c); 

    // copy the array 'c' back from the GPU to the CPU 
    HANDLE_ERROR(cudaMemcpy(c, dev_c, N * sizeof(int), 
           cudaMemcpyDeviceToHost)); 

    // display the results 
    for (int i=0; i<N; i++) { 
     printf("%d + %d = %d\n", a[i], b[i], c[i]); 
    } 

    // free the memory allocated on the GPU 
    HANDLE_ERROR(cudaFree(dev_a)); 
    HANDLE_ERROR(cudaFree(dev_b)); 
    HANDLE_ERROR(cudaFree(dev_c)); 

    return 0; 
} 

謝謝!

回答

1

在SO問題的空間中教CUDA是不可能的。我會盡力回答你的問題,但你應該利用一些資源。如果您不瞭解C或C++,那將會特別困難,因爲典型的CUDA編程依賴於這些編程。

你可能需要一些介紹性研討會here如:使用CUDA C

GPU計算 - 簡介(2010) 介紹到GPU計算的使用CUDA C.概念的基本知識將與演練來說明的代碼示例。沒有先前的GPU計算經驗

使用CUDA C高級GPU計算1(2010) 第一級優化技術,如全局內存優化和處理器利用率。概念將用真實的代碼示例

現在對您的問題進行說明:

有人能解釋你如何分配與「dev_c」,這是一個空指針GPU內存?

​​作爲空指針開始。但cudaMalloc函數allocates GPU memory根據傳遞給它的大小,建立一個指向該分配的指針,並將該指針存儲到指針​​中。它可以做到這一點,因爲我們是passing the address of​​,而不是實際的指針本身。

然後,在調用函數'add'時不傳遞任何'dev_c'值,而是將* c作爲全局函數中的數組並將其作爲函數內部的數組寫入?爲什麼當它沒有在任何地方定義爲數組時,這是可能的?

在C中,一個指針(它是什麼​​是)可以指向單個值或一組值。指針本身不包含它指向多少數據的信息。由於​​正在存儲結果,並且它已被前面的cudaMalloc函數正確初始化,我們可以使用它來將操作的結果存儲在內核中。​​實際上指向(數組)int的存儲區域,其大小由N * sizeof(int)給出,如傳遞給前面的cudaMalloc函數。

最後,在執行以下相加操作時,c [0],c [1]等術語到底會保存嗎?

在C中,當我們有一個函數定義,像這樣:

void my_function(int *c){...} 

這表示該函數中的語句可以引用一個名爲c變量,如果它是一個指針到一個或多個int值(單個值或一組值,從c指向的位置開始存儲)。

當我們調用這個函數,我們可以使用一個名爲作爲參數其他一些變量,函數參數稱爲c,像這樣:

int my_ints[32]; 
my_function(my_ints); 

現在,裏面my_function,無論在參數c被引用,它將使用由(指針)my_ints給出的參數的值

相同的概念適用於cuda函數(內核)及其參數和參數。

+0

謝謝你,現在更有意義了!那麼這是否意味着(數組)c中的值被保存在之前在cudaMalloc((void **)&dev_c,N * sizeof(int))中分配的GPU全局內存中? – user2550888

+0

是的。 'c'的內核用法存儲在爲參數'c'傳遞的參數*中,在這種情況下''dev_c'。而'dev_c'已經預先在設備全局內存中設置了分配的大小。這基本上是C行爲,幾乎與CUDA無關。 –

+0

明白了!再次感謝您的詳細回覆,非常感謝! – user2550888