cuda程式設計與gpu平行計算(三):一個小demo瞭解cuda基本語法
阿新 • • 發佈:2021-01-10
gpu程式的一般步驟
- CPU分配空間給GPU(cudaMalloc)
- CPU複製資料給GPU(cudaMemcpy)
- CPU載入kernels給GPU做計算(Kernel核: 可以理解為C/C++中的一個函式function)
- CPU把GPU計算結果複製回來
過程中,一般要儘量降低資料通訊的消耗,所以如果程式需要複製大量的資料到GPU,顯然不是很合適使用GPU運算,最理想的情況是,每次複製的資料很小,然後運算量很大,輸出的結果還是很小,複製回CPU。
先做一個小demo,對一個8位陣列求平方,很簡單
global 關鍵字那個函式就是在GPU上執行,我們先寫完kernel,那還需要從cpu拿資料過去也就是上面的1和2 這裡我們為了區分cpu和gpu變數,用h_表示cpu變數(host),用d_表示gpu變數(device),host和device我們在之前的概論提了這裡就不解釋了。
#include <stdio.h>
//這個就是kernel
__global__ void square(float* d_out,float* d_in){
int idx = threadIdx.x;
float f = d_in[idx];
d_out[idx] = f * f;
}
int main(int argc,char** argv){
const int ARRAY_SIZE = 8;
const int ARRAY_BYTES = ARRAY_SIZE * sizeof(float);
// 在cpu中定義要輸入的陣列
float h_in[ARRAY_SIZE];
for(int i=0;i<ARRAY_SIZE;i++){
h_in[i] = float(i);
}
float h_out[ARRAY_SIZE];
// 宣告gpu指標
float* d_in;
float* d_out;
// 對應1步驟,給gpu指標分配記憶體空間,和cpu上的資料空間一樣大
cudaMalloc((void**) &d_in,ARRAY_BYTES);
cudaMalloc((void**) &d_out,ARRAY_BYTES);
// 對應步驟2,把cpu資料複製給gpu
cudaMemcpy(d_in,h_in,ARRAY_BYTES,cudaMemcpyHostToDevice);
// 對應步驟3,把kernel也就是square,載入到gpu上執行,1是一個執行緒塊,其中有64個執行緒,1個時鐘週期就可以結束運算
square<<<1,ARRAY_SIZE>>>(d_out,d_in);
// 對應步驟4,把gpu資料複製給cpu
cudaMemcpy(h_out,d_out,ARRAY_BYTES,cudaMemcpyDeviceToHost);
// 輸入結果
for(int i=0;i<ARRAY_SIZE;i++){
printf("%f",h_out[i]);
printf(((i%4) != 3) ? "\t" : "\n");
}
// 釋放記憶體
cudaFree(d_in);
cudaFree(d_out);
return 0;
}
那我們執行一下看看,先編譯,cuda 程式字尾是.cu
nvcc -o square square.cu
square就是我們剛編譯出來的程式
執行一下看看
結果就是0-7的平方,正確