cuda并行编程基础(二)

二、一些基础
    上接: cuda并行编程基础(一)
    (二)cuda基础:gridBlock.cu
        4.总计算量与block、grid的关系

            假设一维数组总计算量为total_c,怎么确定block与grid呢?
            一维数组:
                int cal_array[XX];
                int thd_num=16;
                dim3 block(thd_num);//一般block.x * block.y * block.z <=1024,1024这个值根据显卡性能确定
                dim3 grid((XX + thd_num -1)/thd_num);//这里为何这么计算呢?
            之所以grid.x = XX + thd_num - 1 /thd_num,原因是要保证block*grid >=XX
            二维数组:
                int cal_array[XX][YY];
                int thd_x_num=16,thd_y_num=32;
                dim3 block(thd_x_num,thd_y_num);//一般block.x * block.y * block.z <=1024,1024这个值根据显卡性能确定
                dim3 grid((XX + thd_x_num -1)/thd_x_num,(YY + thd_y_num -1)/thd_y_num);//原因同一维数组
            依次类推,读者可以确定三维数组的计算方法,至于思维数组怎么办?这个嘿嘿,自己想办法啦。
            问题来了,这样的话,grid和block肯定有很多分配方法,对计算会有什么影响吗?答案是肯定的,别着急,以后再学啦,
        5.内存管理
            当然是GPU的内存,跟CPU一样,GPU的内存资源也有限制,申请内存太多会爆掉哦,
            GPU内存分为共享内存和全局内存,所谓共享内存嘛,就是线程可以共享,全局嘛,所有都能访问咯
                CPU:malloc  memcpy  memset  free
                GPU: cudaMalloc  cudaMemcpy  cudaMemset  cudaFree
                cudaError_t cudaMalloc(void **devPtr,size_t size);//只能对GPU数据
                cudaError_t cudaMemcpy(void *dst,const void *src,size_t count,cudaMemcpyKind kind);//可以对GPU也可以对CPU或混合
                cudaError_t cudaMemset(void *devPtr,int value,size_t count);//只能对GPU数据
                cudaError_t cudaFree(void *devPtr);//只能对GPU数据
            可以看到,GPU的内存管理函数相比CPU,无非加了“cuda”,还是很简单的。
            cudaError_t:正确的话返回cudaSuccess,错误返回cudaErrorMemoryAllocation,你可以参看"cuda并行编程基础(一)",或者后面单独对错误处理的章节
            cudaMemcpyKind可以有四个值哦:
                cudaMemcpyHostToHost //CPU到CPU,相当与memcpy
                cudaMemcpyHostToDevice //CPU到GPU
                cudaMemcpyDeviceToHost //GPU到CPU
                cudaMemcpyDeviceToDevice //GPU到GPU  
  
第三个程序,比较重要但很简单  
//gridBlock.cu:block和grid的分配方法,一维数组
/*Authored by alpc40*/
int main(int argc, char **argv)
{
    // 定义总计算量
    int nElem = 1024;
    // 第一种分配法
    dim3 block (1024);
    dim3 grid  ((nElem + block.x - 1) / block.x);
    printf("grid.x %d block.x %d \n", grid.x, block.x);
    // 第二种分配法
    block.x = 512;
    grid.x  = (nElem + block.x - 1) / block.x;
    printf("grid.x %d block.x %d \n", grid.x, block.x);
    // 第三种分配法
    block.x = 256;
    grid.x  = (nElem + block.x - 1) / block.x;
    printf("grid.x %d block.x %d \n", grid.x, block.x);
    // 第四种分配法
    block.x = 128;
    grid.x  = (nElem + block.x - 1) / block.x;
    printf("grid.x %d block.x %d \n", grid.x, block.x);
    // 恢复GPU
    CHECK(cudaDeviceReset());
    return(0);
}


第四个程序,很重要哦
//memoryManage.cu:内存管理
/*Authored by alpc40*/
#define NUM 9//数组大小
//内核函数定义
__global__ void sumArrayOnGpu(int *d_arrayA, int *d_arrayB, int *d_result)
{
 int i = blockDim.x * blockIdx.x + threadIdx.x;
 if (i < NUM)//为什么要加这句呢?因为i的取值范围是[0,11](grid*block=12),要养成良好习惯,防止内存溢出
  d_result[i] = d_arrayA[i] + d_arrayB[i];
}
int main()
{
 int arrayA[NUM] = { 3,4,6,7,8,9,1,19,35 };
 int arrayB[NUM] = { 1,4,7,4,2,8,2,20,33 };
 int result[NUM];//记录CPU结果
 int *d_arrayA, *d_arrayB,*d_result;
 int nBytes=NUM * sizeof(int);//注意拷贝的是字节数,不是个数
 CHECK(cudaMalloc((int **)&d_arrayA, nBytes));//如果觉得CHECK比较烦人,而你不认为这个函数会出错,那么删掉又何妨
 CHECK(cudaMalloc((int **)&d_arrayB, nBytes));//注意申请GPU内存的方法
 CHECK(cudaMalloc((int **)&d_result, nBytes));
 CHECK(cudaMemcpy(d_arrayA, arrayA, nBytes, cudaMemcpyHostToDevice));//注意拷贝的方法
 CHECK(cudaMemcpy(d_arrayB, arrayB, nBytes, cudaMemcpyHostToDevice));
 int thd_num = 4;
 dim3 block(thd_num);//block与grid的定义,结果为(4,1,1),即每个内存块有线程4个
 dim3 grid((NUM + thd_num -1)/thd_num);//结果为(3,1,1),即内存块为3个
 sumArrayOnGpu << <grid, block >> > (d_arrayA,d_arrayB,d_result);//内核函数
 CHECK(cudaMemcpy(result, d_result, nBytes, cudaMemcpyDeviceToHost));
 printf("计算结果:\n");
 for (int i = 0; i < NUM; i++)
  printf(" %d",result[i]);
 printf("\n");
 cudaFree(d_arrayA);//回收GPU内存,一般申请时立马写回收函数,防止忘记导致内存泄露
 cudaFree(d_arrayB);
 cudaFree(d_result);
 cudaDeviceReset();//GPU恢复
 return 0;
}


猜你喜欢

转载自blog.csdn.net/weixin_39212021/article/details/78848659