提升CUDA程序运行效率的几个关键点

目录

1、明确计算机中GPU卡片的计算资源,决定变量的性质(constant,share还是global)以及Grid,Block的维度,充分并合理利用GPU显卡的资源

2、提高PCI接口与GPU显卡的数据吞吐量

3、优化GPU内部存储到处理器之间的数据传输效率

4、利用性能分析工具进行程序性能分析,根据建议进行程序的性能优化


最近由于项目需要,需要用MPI+CUDA混合编程提高程序运行效率。相对于MPI并行程序编程,要想充分利用CUDA的资源利用率,还是要考虑很多方面的内容,根据查找的一些相关资料,将提升GPU显卡吞吐率以及利用效率的方法归纳如下,如有问题,敬请批评指正。下面是进行CUDA编程的大致流程,为了避免混乱,会将相关的详细内容放到链接所示的位置。

1、明确计算机中GPU卡片的计算资源,决定变量的性质(constant,share还是global)以及Grid,Block的维度,充分并合理利用GPU显卡的资源

在进行程序编写前需要明确知道计算机资源,尤其是显卡资源是很宝贵的,在实际编程中需要进行综合考虑,然后再进行参数的具体设置。首先得明白显卡的基本的一些信息,可以通过安装NVIDIA_SAMPLES来进行显卡基本信息的获取,NVIDIA_CUDA-9.1_Samples/1_Utilities/deviceQuery,我的机器的GPU显卡的具体信息如下:

这里面的每一条信息都是很重要的,其中我们平时用的最多的还是“Total amount of global memory,Multiprocessors,  CUDA Cores/MP,L2 Cache Size,Maximum Texture Dimension Size (x,y,z),Total amount of constant memory,Total amount of shared memory per block,Total number of registers available per block,Warp size,Maximum number of threads per multiprocessor,Maximum number of threads per block,Max dimension size of a thread block (x,y,z),Max dimension size of a grid size    (x,y,z),Integrated GPU sharing Host Memory,Support host page-locked memory mapping,Device has ECC support”等等,在地球物理相关的CUDA程序编写中,关注这些参数就已经足够了。对于一个程序在运行时对显卡资源的分配问题,详细内容可以点击下面两个链接。

具体可参考:GPU硬件结构和程序具体参数设置_yu132563的专栏-CSDN博客

CUDA程序编写具体参数设置_yu132563的专栏-CSDN博客

2、提高PCI接口与GPU显卡的数据吞吐量

  • 使用流并行及统一内存、zerocopy等方法掩盖PCI接口与GPU显卡之间进行数据传输的时间延迟
  • 核函数执行和数据传输的重叠

3、优化GPU内部存储到处理器之间的数据传输效率

主要方法如下:

  • 使用共享内存减少全局内存读取次数
  • 减少全局内存的重复数据的重复访问,此处大有学问,需要设计我们的线程组织模式,最大可能利用共享内存,可参考矩阵乘法优化问题;
  • 把全局内存绑定为纹理
  • 纹理的存取速度要远高于全局内存

  • 减少bank conflict, 让不同线程读取连续内存
  • Tesla 的每个 SM 拥有 16KB 共享存储器,用于同一个线程块内的线程间通信。为了使一个 half-warp 内的线程能够在一个内核周期中并行访问,共享存储器被组织成 16 个 bank,每个 bank 拥有 32bit 的宽度,故每个 bank 可保存 256 个整形或单精度浮点数,或者说目前的 bank 组织成了 256 行 16 列的矩阵。如果一个 half-warp 中有一部分线程访问属于同一bank 的数据,则会产生 bank conflict,降低访存效率,在冲突最严重的情况下,速度会比全局显存还慢,但是如果 half-warp 的线程访问同一地址的时候,会产生一次广播,其速度反而没有下降。在不发生 bank conflict 时,访问共享存储器的速度与寄存器相同。在不同的块之间,共享存储器是毫不相关的。
  • 尺寸和对齐的要求内存对齐
  • 因为GPU 上的内存控制器,从某个固定的倍数地址开始读取,才会有最高的效率(例如 16 bytes 的倍数)。分配内存时使用cudaMallocPitch替代cudaMalloc,相应 cudaMemcpy2D替代 cudaMemcpy。(这其实和(2)中原理类似)

  • 合并访问
  • 详情可参考:CUDA总结:合并访问coalesced_Kelvin_Yan的专栏-CSDN博客_cuda合并访问
  • 使用流并行
  • 流并行属于,任务级别的并行,当我们有几个互不相关的任务时,可以写多个核函数,资源允许的情况下,我们将这些核函数装载到不同流上,然后执行,这样可以实现更粗粒度的并行。
    实验中发现,流并行的效率和增加一个线程网格的维度的方法的效率一样。也可以使用没线程默认流来进行流并行

4、利用性能分析工具进行程序性能分析,根据建议进行程序的性能优化

nvvp和nvprof工具进行性能分析,进一步提高计算性能

参考文献:

CUDA中Bank conflict冲突_smsmn的专栏-CSDN博客

CUDA总结:合并访问coalesced_Kelvin_Yan的专栏-CSDN博客_cuda合并访问

CUDA程序优化方法_changyi9995的博客-CSDN博客_cuda优化

CUDA2.2-原理之存储器访问 - 仙守 - 博客园

CUDA编程——zero copy_道道道人间道的博客-CSDN博客_cuda zerocopy

cuda Global Memory Access - 灰太狼锅锅 - 博客园

CUDA学习--CUDA流_Yi_M的博客-CSDN博客_cuda 流

CUDA编程第六章: 流和并发_Janus-CSDN博客

CUDA 7 Stream流简化并发性 - 吴建明wujianming - 博客园

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值