原文連接html
系列文章:git
-code
、-arch
、-gencode
選項在介紹編碼相關內容以前,一個更重要的話題是什麼類型的問題適合用GPU進行解決。程序員
GPU於CPU相比,有着驚人的核數、運算單元及內存帶寬。對於給定問題,若是有辦法把它分解爲多個獨立的子問題並行解決,那麼GPU頗有可能提供比CPU更好的性能。所謂「獨立」,指的是所分解的子問題知足:github
矩陣相乘就是一個很好的例子,對矩陣相乘結果中各個元素的計算之間沒有任何依賴關係,可以很好地經過GPU進行並行。固然對於一些問題,可能沒辦法馬上想出並行的辦法,可是卻存在可高效並行的問題分解辦法,比方說:編程
(思考題)數組
對於手頭的問題,若是可以順利對問題進行分解,那麼就有可能利用GPU提供的硬件特性及編程模型對其進行高效解決。bash
if (threadIdx.x % 2 == 0) {
// Some work
} else {
// Other work
}
複製代碼
說點別的異步
32個thread組成的調度單元爲何叫warp?緣由是thread有線的意思,而warp是織布機相關的一個把多個thread固定注的裝置,因而就取了這個比喻:
ide
就像寫CPU代碼時會受到CPU核數、內存空間、訪存速度的限制同樣,GPU編程模型裏也須要留意相關的資源限制:函數
CUDA編程中的常見流程是:
Cuda樣例代碼中的vectorAdd
完成的任務是對長爲numElements
的兩個數組h_A
、h_B
進行對應元素加合,並將結果存入h_C
中。接下來咱們以vectorAdd
爲例,說明這一流程:
cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);
cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice);
複製代碼
__global__ void
vectorAdd(const float *A, const float *B, float *C, int numElements)
{
int i = blockDim.x * blockIdx.x + threadIdx.x;
if (i < numElements)
{
C[i] = A[i] + B[i];
}
}
複製代碼
作的事情就是每一個thread負責根據本身所在的thread block及threadIdx計算出本身所應處理的數組下標,並對這一下標對應的元素完成一次加合計算。
<<<blocksPerGrid, threadsPerBlock>>>
指定了thread block數量及每一個block中的thread數量。vectorAdd<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, d_C, numElements);
複製代碼
cudaMemcpy(h_C, d_C, size, cudaMemcpyDeviceToHost);
複製代碼
一個cuda程序最重要的部分就完成了。完整代碼中還包含了內存的分配、cuda調用的錯誤檢查等內容,完整代碼可見cuda安裝目錄下的samples/0_Simple/vectorAdd
。