CUDA( ) 向量求和運算

2021-09-19 17:31:57 字數 2649 閱讀 5815

問題描述:將兩組資料對應的元素兩兩相加,並將結果儲存在第三個陣列中。即向量求和運算

目錄

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...