問題描述:將兩組資料對應的元素兩兩相加,並將結果儲存在第三個陣列中。即向量求和運算
目錄
1.基於cpu的向量求和
**分析:
問題:索引取值範為0 到 n-1 ,下面兩種函式add()有什麼區別嗎?
完整的**實現及執行結果:
2.基於gpu的向量求和
**分析:
問題:<<<>>>裡面引數式什麼含義?
問題:既然gpu將執行kernel的n個副本,那如何在**中知道當前正在執行是哪乙個block?
問題:為什麼不是blockidx?而是blockidx.x?
問題:進一步解釋block是如何定位kernel?
問題:為什麼要判斷tid是否小於n?
問題:block的數量是否可以任意設定?
完整的**實現及執行結果:
3.小結
void add(int* a,int* b,int* c)
}void add(int* a,int* b,int* c)
}
while迴圈雖然比較複雜,但是能夠使**在擁有多個cpu或者gpu核的系統上執行。
如下圖:假如雙核處理器,每次遞增大小改為2,核1將偶數索引的元素相加,而核2將奇數索引的元素相加,即相當與每個cpu核上執行以下**。
後面再實現這個**,執行緒排程機制的實際運**況灰常複雜
void add(int* a,int* b,int* c)
}void add(int* a,int* b,int* c)
}
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include #define n 10
void add(int* a,int* b,int* c)
}int main(void)
}
blockidx是乙個內建變數,在cuda執行時中已經預先定義了這個變數,而且這個變數的名字就是變數的作用,變數中包含的值就是當前執行device code的block的索引。
因為cuda支援二維的block陣列。對於二維空間計算問題,如矩陣數**算或者影象處理,使用二維索引往往會帶來很大的遍歷,(後續使用再分析),避免將線性所以轉化為矩形索引。
block的集合稱為grid。在本程式中,我們使用的是一維的grid,其中包含n個block。每個block的blockidx.x值是不同的,如:第乙個block的blockidx.x=0,第n個block的block.x=n-1。
所以在本程式中,有n個block,每個block都執行相同的device code,但每個block的blockidx.x是不同的,所以當n個block並行執行時,執行時用相應的block索引來替換blockidx.x。每個block執行的block code如下。
__global__ void add(int* a,int* b,int* c)
}//int tid = 1 ....int tid = n-1;
......
__global__ void add(int* a,int* b,int* c)
}
在我們調整引數<<<>>>,tid總是小於n的,因為我們在kernel中都是這麼假設的。但是我們任然有理由懷疑可能會出現非法的記憶體訪問,這將會造成一種糟糕的情況。
在啟動block陣列時,陣列每一維的最大數量都不能超過65535,這是一種硬體限制,如果啟動的block數量超過了這個限制,那麼程式將執行失敗。
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include #define n 10
__global__ void add(int* a,int* b,int* c)
}int main(void){
int a[n],b[n],c[n];
int *dev_a,*dev_b,*dev_c;
//在cpu上為陣列『a』和『b』賦值
//為什麼要在cpu上對輸入陣列賦值,其實沒啥特殊原因?
//假設用於從硬碟上讀取資料,或者是其他應用程式中的乙個步驟,並且輸入陣列由其他演算法生成
for (int i = 0; i>>(dev_a,dev_b,dev_c);
//4.將陣列『c』從gpu複製到cpu
cudamemcpy(c, dev_c, n * sizeof(int), cudamemcpydevicetohost);
//在cpu上顯示結果
本次學習筆記的總結,我們學到了如何告訴cuda執行時在block上並行執行程式,我們把在gpu上啟動的block集合稱為乙個grid。grid既可以是一維的block集合,也可以是二維的block集合。kernel的每個副本都可以通過內建變數blockid來判斷哪個block正在執行它。同樣也可以通過內建變數griddim來獲得grid的大小。後續會用到
CUDA程式設計實戰 並行向量求和
多個並行執行緒塊完成兩個向量的求和 如下 使用了10個並行執行緒塊 include include book.h using namespace std define n 10 global void add int a,int b,int c int main void int a n b n c...
CUDA學習筆記(2)對任意向量長度求和
使用128個執行緒塊和128個執行緒來完成此項操作。值得注意的是,在編譯過程中,發現這個庫一出現就會導致error msb3721出現。雖然之前了解到msb3721往往是由於有些引用到的庫出問題,但是這個基本的庫難道都沒法用嗎?但是也只能放棄用cout輸出,而改用printf,結果成功。includ...
cuda 入門 向量相加
檔名為main.cu include include 兩個向量加法kernel,grid和block均為一維 global void add float x,float y,float z,int n int main 申請device記憶體 float d x,d y,d z cudamalloc...