CUDA 第乙個CUDA程式 addVector

2021-07-08 15:31:01 字數 3780 閱讀 1728

本文主要通過對兩個浮點陣列中的資料進行相加,並將其結果放入第三個陣列中。其演算法分別在cpu、gpu上分別執行,並比較了所需時間,強烈感受到gpu的平行計算能力。這裡,每個陣列的元素大小為30000000個。

#include #include #include #include // for the cuda runtime routines (prefixed with "cuda_")

#include //該函式宣告為了__global__,表示由gpu呼叫執行.

//其功能為將陣列pa、pb中對應位置的資料相加,並將結果放入陣列pc的對應位置上

//每個陣列的索引大小為size

__global__

void add(const float * pa, const float * pb, float * pc, unsigned int size)

int main()

//cpu segment

//begin use cpu comput

clock_t starttime, endtime;

starttime = clock();

for (int i = 0; i < numelement; ++i)

endtime = clock();

//end use cpu comput

printf("use cpu comput finish!\n");

printf("use total time = %fs\n", (endtime - starttime) / 1000.f);

printf("\n\n");

//gpu segment

float *pd, *pe, *pf;

cudaerror_t err = cudasuccess;

//malloc memory

err = cudamalloc(&pd, totalsize);

if (err != cudasuccess)

err = cudamalloc(&pe, totalsize);

if (err != cudasuccess)

err = cudamalloc(&pf, totalsize);

if (err != cudasuccess)

//copy data from pa pb pc to pd pe pf

err = cudamemcpy(pd, pa, totalsize, cudamemcpyhosttodevice);

if (err != cudasuccess)

err = cudamemcpy(pe, pb, totalsize, cudamemcpyhosttodevice);

if (err != cudasuccess)

//begin use gpu comput

starttime = clock();

int threadperblock = 1024;

int numblock = (numelement - 1) / threadperblock + 1;

add << > >(pd, pe, pf, numelement);

err = cudagetlasterror();

if (err != cudasuccess)

endtime = clock();

printf("use gpu comput finish!\n");

printf("use time : %fs\n",(endtime - starttime) / 1000.f);

//end use gpu comput

//copu data from device to host

err = cudamemcpy(pc, pf, totalsize, cudamemcpydevicetohost);

if (err != cudasuccess)

//check data

for (int i = 0; i < numelement; ++i) }

//釋放裝置上的記憶體

cudafree(pd);

cudafree(pe);

cudafree(pf);

//在程式退出前,呼叫該函式重置該裝置,使驅動去清理裝置狀態,並且在程式退出前所有的資料將被刷出。

__host__  cudaerror_t  cudamalloc(void **devptr, size_t size);
該函式主要用來分配裝置上的記憶體(即視訊記憶體中的記憶體)。該函式被宣告為了__host__,即表示被host所呼叫,即在cpu中執行的**所呼叫。

返回值:為cudaerror_t型別,實質為cudaerror的列舉型別,其中定義了一系列的錯誤**。如果函式呼叫成功,則返回cudasuccess。

第乙個引數,void ** 型別,devptr:用於接受該函式所分配的記憶體位址

第二個引數,size_t型別,size:指定分配記憶體的大小,單位為位元組

__host__  cudaerror_t  cudafree(void *devptr);
該函式用來釋放先前在裝置上申請的記憶體空間(通過cudamalloc、cudamallocpitch等函式),注意,不能釋放通過標準庫函式malloc進行申請的記憶體。

返回值:為錯誤**的型別值

第乙個引數,void**型別,devptr:指向需要釋放的裝置記憶體位址

__host__ cudaerror_t  cudamemcpy(void *dst, const void *src, size_t count, enum cudamemcpykind kind);
該函式主要用於將不同記憶體段的資料進行拷貝,記憶體可用是裝置記憶體,也可用是主機記憶體

第二個引數,const void *型別,src:源記憶體位址

第三個引數,size_t型別,count:將要進行拷貝的位元組大小

第四個引數,enum cudamemcpykind型別,kind:拷貝的型別,決定拷貝的方向

cudamemcpykind型別如下:

enum __device_builtin__ cudamemcpykind

;

cudamemcpykind決定了拷貝的方向,即是從主機的記憶體拷貝至裝置記憶體,還是將裝置記憶體拷貝值主機記憶體等。cudamemcpy內部根據拷貝的型別(kind)來決定呼叫以下的某個函式:

::cudamemcpyhosttohost, 

::cudamemcpyhosttodevice,

::cudamemcpydevicetohost,

::cudamemcpydevicetodevice

__host__ cudaerror_t  cudadevicereset(void);
該函式銷毀當前程序中當前裝置上所有的記憶體分配和重置所有狀態,呼叫該函式達到重新初始該裝置的作用。應該注意,在呼叫該函式時,應該確保該程序中其他host執行緒不能訪問該裝置!

cuda筆記 第乙個cuda程式

釋放gpu中的記憶體cudafree cuda函式的定義 global 定義在gpu上,可以在cpu上呼叫的函式 device 定義在gpu上,由gpu呼叫函式 host 在cpu上定義的函式,一般與 device 一起用 在gpu上開闢空間 cudamalloc devptr,byte size ...

CUDA程式設計(一)第乙個CUDA程式

cuda compute unified device architecture 是顯示卡廠商nvidia推出的運算平台。是一種通用平行計算架構,該架構使gpu能夠解決複雜的計算問題。說白了就是我們可以使用gpu來並行完成像神經網路 影象處理演算法這些在cpu上跑起來比較吃力的程式。通過gpu和高並...

CUDA程式設計(一)第乙個CUDA程式

cuda compute unified device architecture 是顯示卡廠商nvidia推出的運算平台。是一種通用平行計算架構,該架構使gpu能夠解決複雜的計算問題。說白了就是我們可以使用gpu來並行完成像神經網路 影象處理演算法這些在cpu上跑起來比較吃力的程式。通過gpu和高並...