1. 程式人生 > >CUDA入門——環境搭建,hello world cuda(1)

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。