cuda矩阵加法
1、获取gpu设备数量(在主机和设备中都可以调用)
int iDeviceCount = 0;
cudaGetDeviceCount(&iDeviceCount);
2、设置gpu执行时所使用的设备(只能在主机中调用)
int iDev = 0;
cudaSetDevice(iDev);
3、内存管理
1、cuda通过内存分配、数据传递、内存初始化、内存释放进行内存管理
2、
标准c语言内存管理函数 | cuda内存管理函数 |
---|---|
malloc | cudaMalloc |
memcoy | cudaMemcpy |
memset | cudaMemset |
free | cudaFree |
3、cudaMalloc(void **devPtr, size_t size);
4、cudaMemcpy(void *dst,const void *src , size_t count, cudaMemcpyKind kind)
5、cudaMemset(void *devPtr, int value, size_t count)
6、cudaFree(void *devPtr)
4、自定义设备函数
1、设备函数:
1、定义只能执行在gpu设备上的函数为设备函数
2、设备函数只能被核函数或者其他设备函数调用
3、设备函数用__device__修饰
2、核函数
1、用__global__修饰的函数称为核函数,一般有主机调用,在设备中执行
2、__global__修饰符既不能和__host__同时使用也不可与__device__同时使用
3、主机函数
1、主机端的普通c++函数可用__host__修饰
2、对于主机端的函数,__host__修饰符可省略
3、可以用__host__和__device__同时修饰一个函数减少冗余代码。编译器会针对主机和设备分别编译该函数
#include <stdio.h>
#include <stdlib.h>__global__ void addFromGpu(float *A, float *B, float *C, const int N)
{const int bid = blockIdx.x;const int tid = threadIdx.x;const int id = tid * bid * blockDim.x;C[id] = A[id] + B[id];
}void setGpu()
{//检测计算机gpu数量int iDeviceCount = 0;cudaError_t error = cudaGetDeviceCount(&iDeviceCount);if(error != cudaSuccess || iDeviceCount == 0){printf("No CUDA campatable gpu found\n");exit(-1);}elseprintf("The count of gpus is %d.\n",iDeviceCount);//设置执行int iDev = 0;error = cudaSetDevice(iDev);if(error != cudaSuccess){printf("fail to set gpu 0 for computing.\n");exit(-1);}elseprintf("set gpu 0 for computing.");}void initialData(float *addr, int elemCount)
{for(int i = 0;i < elemCount; i++){addr[i] = (float)(rand() & 0xFF) / 10.f;}
}int main()
{//1、设置gpusetGpu();//2、分配主机内存和设备内存,并初始化int iEleCount = 512; //设置元素数量size_t stBytesCount = iEleCount * sizeof(float); //字节数//(1) 分配主机内存,并初始化float *fpHost_A, *gpHost_B, *fpHost_C';fpHost_A = (float *)malloc(stBytesCount);gpHost_B = (float *)malloc(stBytesCount);fpHost_C = (float *)malloc(stBytesCount);if(fpHost_A != NULL && fpHost_B != NULL && fpHost_C != NULL){memset(fpHost_A, 0, stBytesCount);//主机内存初始化为0memset(fpHost_B, 0, stBytesCount);memset(fpHost_C , 0, stBytesCount);}else{if(fpHost_A)free(fpHost_A);if(fpHost_B)free(fpHost_B);if(fpHost_C)free(fpHost_C);printf("fail to malloc host memory!\n");exit(-1);}//(2) 分配设备内存,并初始化float *fpDevice_A, *fpDevice_B, *fpDevice_C;cudaMalloc((float**)&fpDevice_A, stBytesCount);cudaMalloc((float**)&fpDevice_B, stBytesCount);cudaMalloc((float**)&fpDevice_C, stBytesCount); if(fpDevice_A != NULL && fpDevice_B != NULL && fpDevice_C != NULL){cudaMemset(fpDevice_A, 0, stBytesCount);cudaMemset(fpDevice_B, 0, stBytesCount);cudaMemset(fpDevice_C, 0, stBytesCount);}else{printf("fail to allocate memory!\n");free(fpHost_A);free(fpHost_B);free(fpHost_C);exit(-1);}//3、初始化主机中数据srand(666);initialData(fpHost_A, iEleCount);initialData(fpHost_B, iEleCount);//4、数据从主机复制到设备cudaMemcpy(fpDevice_A, fpHost_A, stBytesCount, cudaMemCpyHostToDevice);cudaMemcpy(fpDevice_B, fpHost_B, stBytesCount, cudaMemCpyHostToDevice);cudaMemcpy(fpDevice_C, fpHost_C, stBytesCount, cudaMemCpyHostToDevice);//5、调用核函数在设备中进行计算dim3 block(32);dim3 grid(iEleCount / 32);addFromGpu<<<grid, block>>>(fpDevice_A, fpDevice_B, fpDevice_C, iEleCount);cudaDevicesSynchronize();//6、将计算得到的数据从设备传给主机cudaMemcpy(fpHost_C, fpDevice_C, stBytesCount, cudaMemCpyDeviceToHost);for(int i = 0;i < 10; i++){printf("idx=%2d\tmatrix_A:%.2f\tmatrix_B:%.2f\tresult:%.2f\n", i+1, fpHost_A[i], fpHost_B[i], fpHost_C[i]);}//7、释放主机与设备内存free(fpHost_A);free(fpHost_B);free(fpHost_C);cudaFree(fpDevice_A);cudaFree(fpDevice_B);cudaFree(fpDevice_C);cudaDeviceReset();return 0;
}