-
使用共享内存减少全局内存读取次数
减少全局内存的重复数据的重复访问,此处大有学问,需要设计我们的线程组织模式,最大可能利用共享内存,可参考矩阵乘法优化问题; -
把全局内存绑定为纹理;
纹理的存取速度要远高于全局内存 -
减少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 时,访问共享存储器的速度与寄存器相同。在不同的块之间,共享存储器是毫不相关的。
详细内容请参考:CUDA中Bank conflict冲突 -
尺寸和对齐的要求内存对齐。
因为GPU 上的内存控制器,从某个固定的倍数地址开始读取,才会有最高的效率(例如 16 bytes 的倍数)。分配内存时使用cudaMallocPitch替代cudaMalloc,相应 cudaMemcpy2D替代 cudaMemcpy。(这其实和(2)中原理类似)。 -
合并访问
CUDA总结:合并访问coalesced -
使用流并行
流并行属于,任务级别的并行,当我们有几个互不相关的任务时,可以写多个核函数,资源允许的情况下,我们将这些核函数装载到不同流上,然后执行,这样可以实现更粗粒度的并行。
实验中发现,流并行的效率和增加一个线程网格的维度的方法的效率一样。以上代码可以采用增加线程块数目的方法来实现
CUDA程序优化方法
最新推荐文章于 2022-06-07 08:48:31 发布