CUDA編程的學習,需要熟練的掌握C/C++編程的基礎及操作系統(tǒng)方面的知識。
只有主機代碼的cuda程序在cuda程序中,既有純粹的c++代碼,又有不屬于c++代碼的真正的cuda代碼。cuda程序的編譯器為nvcc,在編譯一個cuda程序時,純粹的c++代碼使用g++等編譯器編譯,剩下的就由nvcc負責編譯。cuda的程序一般命名為xxx.cu
#includeint main()
{printf("hello world!\n");
return 0;
}
和c++的編譯指令類似:-g表示可以debug
nvcc -g hello.cu -o hello
前面使用主機的cuda程序,雖然使用cuda編譯,但是并沒有使用GPU。GPU只是一個設備,要它工作的話,需要主機(一般是CPU)給它下達指令。一個利用GPU的cuda程序既要有主機代碼,也要有設備代碼。主機對設備的調(diào)用是通過核函數(shù)來實現(xiàn)。
主要結(jié)構(gòu)的形式:
int main()
{主機代碼
核函數(shù)的調(diào)用
主機代碼
return 0;
}
cuda里的核函數(shù)核函數(shù)存在一些要求(大部分在之后都會有例子說明):
__global__ void hello_from_gpu()
{printf("hello world from the gpu!\n");
}
void __global__ hello_from_gpu()
{printf("hello world from the gpu!\n");
}
一個GPU中有很多計算核心,可以支持很多線程。設備在調(diào)用核函數(shù)時要明確使用多少個線程。
hello_from_gpu<<<1,1>>>(); // 設備只使用一個線程
(3)核函數(shù)的調(diào)用:要有<<<>>>,用這個來指明設備中要指派多少個線程。其中<<<網(wǎng)格大小,線程塊大小>>>。網(wǎng)格大小:可以看作是線程塊的個數(shù)。線程塊大小:可以看作是每個線程塊包含的線程數(shù)量。核函數(shù)中總的線程數(shù)等于網(wǎng)格大小乘以線程塊大小。
(4) 函數(shù)名無特殊要求,支持C++中的重載。
(5) 核函數(shù)不支持可變數(shù)量的參數(shù)列表,參數(shù)的個數(shù)必須確定。
(6) 除非使用統(tǒng)一的內(nèi)存編程機制,否則傳給核函數(shù)的參數(shù)有數(shù)組或指針類型時,必須是指向設備的內(nèi)存。
(7) 核函數(shù)不能成為一個類的成員。通常的做法是用一個包裝函數(shù)調(diào)用核函數(shù),而將包裝函數(shù)定義為類的成員。
(8) 在GPU的計算能力3.5之前核函數(shù)之間不能相互調(diào)用,3.5之后引入動態(tài)并行機制后,可以相互調(diào)用了,甚至可以遞歸。
cudaDeviceSynchronize():cuda運行時的API函數(shù),作用是同步主機與設備,因為核函數(shù)的調(diào)用是異步的,主機發(fā)出調(diào)用核函數(shù)指令后不等待核函數(shù)執(zhí)行完畢會立即執(zhí)行程序后面的語句。
使用和函數(shù)的cuda程序:
#include__global__ void hello_from_gpu()
{printf("hello world from the gpu!\n");
}
int main()
{hello_from_gpu<<<1,1>>>();
cudaDeviceSynchronize();
return 0;
}
cuda中的線程組織
多個線程的核函數(shù)和函數(shù)代碼執(zhí)行的指令是“單指令-多線程”,即每一個線程都執(zhí)行同一串指令。如下代碼,會打印出8行同樣的文字
#include__global__ void hello_from_gpu()
{printf("hello world from the gpu!\n");
}
int main()
{hello_from_gpu<<<2,4>>>();
cudaDeviceSynchronize();
return 0;
}
每個線程在核函數(shù)中都有一個唯一的身份標識,我們可以通過線程索引來獲取到底是哪一個線程執(zhí)行的代碼。
在核函數(shù)內(nèi)部,grid_size和block_size的值保存在兩個內(nèi)建變量中。
#include__global__ void hello_from_gpu()
{const int bid = blockDim.x;
const int tid = threadIdx.x;
printf("hello world from %d block and the %d thread!\n",bid,tid);
}
int main()
{hello_from_gpu<<<2,4>>>();
cudaDeviceSynchronize();
return 0;
}
其實線程塊的(0,1)順序不一定,因為cuda的計算特征是每個線程塊的計算是相互獨立的。
內(nèi)建變量是使用c++中的結(jié)構(gòu)體或者類定義的。
blockIdx和threadIdx是類型為unit3的變量,是一個結(jié)構(gòu)體類型,具有x,y,z這3個成員。
使用多維線程的示例:
#include__global__ void hello_from_gpu()
{const int b = blockIdx.x;
const int tx = threadIdx.x;
const int ty = threadIdx.y;
printf("hello world from %d block and the (%d,%d) thread!\n",b,tx,ty);
}
int main()
{const dim3 block_size(2,4);
hello_from_gpu<<<1,block_size>>>();
cudaDeviceSynchronize();
return 0;
}
CUDA編程是通往高性能計算的道路,學習掌握cuda編程,將其運用在一些計算機視覺的部署任務中是十分常見和高效的。
參考:如博客內(nèi)容有侵權(quán)行為,可及時聯(lián)系刪除!
CUDA 編程:基礎與實踐
https://docs.nvidia.com/cuda/
你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
分享文章:CUDA編程筆記(1)-創(chuàng)新互聯(lián)
URL分享:http://chinadenli.net/article42/dedihc.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、軟件開發(fā)、全網(wǎng)營銷推廣、品牌網(wǎng)站設計、搜索引擎優(yōu)化、營銷型網(wǎng)站建設
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)