CUDA入門——環境搭建,hello world cuda(1)
一般而言,CUDA程式的基本模式是:
分配記憶體空間和視訊記憶體空間
初始化記憶體空間
將要計算的資料從記憶體上覆制到視訊記憶體上
執行kernel計算
將計算後視訊記憶體上的資料複製到記憶體上
處理複製到記憶體上的資料
註釋:// This is the REAL "hello world" for CUDA! // It takes the string "Hello ", prints it, then passes it to CUDA with an array // of offsets. Then the offsets are added in parallel to produce the string "World!" // By Ingemar Ragnemalm 2010 #include <stdio.h> const int N = 16; const int blocksize = 16; __global__ void hello(char *a, int *b) { a[threadIdx.x] += b[threadIdx.x]; } int main() { char a[N] = "Hello \0\0\0\0\0\0"; int b[N] = {15, 10, 6, 0, -11, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; char *ad; int *bd; const int csize = N*sizeof(char); const int isize = N*sizeof(int); printf("%s", a); cudaMalloc( (void**)&ad, csize ); cudaMalloc( (void**)&bd, isize ); cudaMemcpy( ad, a, csize, cudaMemcpyHostToDevice ); cudaMemcpy( bd, b, isize, cudaMemcpyHostToDevice ); dim3 dimBlock( blocksize, 1 ); dim3 dimGrid( 1, 1 ); hello<<<dimGrid, dimBlock>>>(ad, bd); cudaMemcpy( a, ad, csize, cudaMemcpyDeviceToHost ); cudaFree( ad ); cudaFree( bd ); printf("%s\n", a); return EXIT_SUCCESS; }
函式型別限定符,用來確定函式是在CPU還是在GPU上執行,以及這個函式是從CPU呼叫還是從GPU呼叫。
__device__,__device__表示從GPU上呼叫,在GPU上執行;
__global__,__global__表示在CPU上呼叫,在GPU上執行,也就是所謂的核心(kernel)函式;核心主要用來執行多執行緒呼叫。
__host__,__host__表明在CPU上呼叫,在CPU上執行,這是預設時的情況,也就是傳統的C函式。CUDA支援__host__和__device__的聯用,表示同時為主機和裝置編譯。此時這個函式不能出現多執行緒語句。
變數型別限定符,用來規定變數儲存什麼位置上。在傳統的CPU程式上,這個任務由編譯器承擔。在CUDA中,不僅要使用主機端的記憶體,還要使用裝置端的視訊記憶體和GPU片上的暫存器、共享儲存器和快取。在CUDA儲存器模型中,一共抽象出來了8種不同的儲存器。複雜的儲存器模型使得必須要使用限定符要說明變數的儲存位置。
__device__,__device__表明宣告的資料存放在視訊記憶體中,所有的執行緒都可以訪問,而且主機也可以通過執行時庫訪問;
__shared__,__shared__表示資料存放在共享儲存器在,只有在所在的塊內的執行緒可以訪問,其它塊內的執行緒不能訪問;
__constant__,__constant__表明資料存放在常量儲存器中,可以被所有的執行緒訪問,也可以被主機通過執行時庫訪問;
執行配置運算子<<< >>>,用來傳遞核心函式的執行引數。執行配置有四個引數,第一個引數宣告網格的大小,第二個引數宣告塊的大小,第三個引數宣告動態分配的共享儲存器大小,預設為0,最後一個引數宣告執行的流,預設為0。
五個內建變數,用於在執行時獲得網格和塊的尺寸及執行緒索引等資訊
gridDim, gridDim是一個包含三個元素x,y,z的結構體,分別表示網格在x,y,z三個方向上的尺寸,雖然其有三維,但是目前只能使用二維;
blockDim, blockDim也是一個包含三個元素x,y,z的結構體,分別表示塊在x,y,z三個方向上的尺寸,對應於執行配置中的第一個引數,對應於執行配置的第二個引數;
blockIdx, blockIdx也是一個包含三個元素x,y,z的結構體,分別表示當前執行緒所在塊在網格中x,y,z三個方向上的索引;
threadIdx, threadIdx也是一個包含三個元素x,y,z的結構體,分別表示當前執行緒在其所在塊中x,y,z三個方向上的索引;
warpSize,warpSize表明warp的尺寸,在計算能力為1.0的裝置中,這個值是24,在1.0以上的裝置中,這個值是32。