CUDA学习系列教程(四)

GPU程序一般步骤

  • CPU分配空间给GPU(cudaMalloc)
  • CPU复制数据给GPU(cudaMemcpy)
  • CPU加载kernels给GPU做计算
  • CPU把GPU计算结果复制回来

过程中,一般要尽量降低数据通讯的消耗,所以如果程序需要复制大量的数据到GPU,显然不是很合适使用GPU运算,最理想的情况是,每次复制的数据很小,然后运算量很大,输出的结果还是很小,复制回CPU。

核函数是GPU每个thread上运行的程序。必须通过__gobal__函数类型限定符定义。形式如下:
global void kernel(param list){}
核函数只能在主机端调用,调用时必须申明执行参数。调用形式如下:Kernel<<<Dg,Db,Ns,S>>>(param list);
<<<>>>运算符内是核函数的执行参数,告诉编译器运行时如何启动核函数,用于说明内核函数中的线程数量,以及线程是如何组织的。
<<<>>>运算符对kernel函数完整的执行配置参数形式是<<<Dg,Db,Ns,S>>>

  • 参数Dg用于定义整个grid的维度和尺寸,即一个grid有多少个block.为dim3类型。Dim3Dg(Dg.x,Dg.y,1)表示grid中每行有Dg.x个block,每列有Dg.y个block,第三维恒为1(目前一个核函数只有一个grid)。整个grid中共有Dg.x*Dg.y个block,其中Dg.x和Dg.y最大值为65535。
  • 参数Db用于定义一个block的维度和尺寸,即一个block有多少个thread.为dim3类型。Dim3 Db(Db.x,Db.y,Db.z)表示整个block中每行有Db.x个thread,每列有Db.y个thread,高度为Db.z。Db.x和Db.y最大指为512,Db.z 最大值为62。一个blockade中共有Db.xDb.yDb.z个thread。计算能力为1.0,1.1的硬件该乘积的最大值为768,计算能力为1.2,1.3的硬件支持的最大值为1024。
  • 参数Ns是一个可选参数吗,用于设置每个block除了静态分配的shared Memory以外,最多能动态分配的shared memory大小,单位为byte。不需要动态分配时该值为0或省略不写。
  • 参数S是一个cudaStream_t类型的可选参数,初始值为零,表示该核函数处在哪个流之中。

CUDA代码高效策略

  • 高效公式:最大化计算强度:Math/Memory.
    1.最大化每个线程的计算量
    2.最小化每个线程的内存读取速度
    (1)每个线程读取的数据量少
    (2)每个线程读取的速度快

     	 					本地内存>共享内存>全局内存
     	 					合并全局内存
    
  • 合并全局内存

  • 避免线程发散
    1.kernel中做条件判断
    2.循环长度不一

CUDA 中的各种内存的代码使用

  • 全局内存
  • 共享内存
  • 本地内存

CUDA同步操作

  • 原子操作
  • 同步函数
  • CPU/GPU同步

猜你喜欢

转载自blog.csdn.net/weixin_42104289/article/details/83658470