CUDA程序基本优化

52 阅读3分钟
  • Parallel Reduction 并行规约
  • Warp 分割
  • Memory Coalescing 访存合并
  • Bank 冲突
  • SM 资源动态分割
  • 数据预读
  • 指令混合
  • 循环展开

有效的数据并行算法 + 针对GPU架构特性的优化 = 最优性能

Parallel Reduction 并行规约

tmp7557.png

tmp3F04.png

tmpEEE1.png

tmp2E6B.png

tmp60A8.png

tmpE0CA.png

如果我们改进一下,也就是减少空闲线程,修改索引方式。

tmp6DB4.png

tmpA318.png

代码如下:

tmpA883.png

第二种好处在于可以释放多余资源。

Warp 分割

线程块内如何划分warp

通晓:warp分割有助于:减少分支发散,让warp尽早完工

(1)warp是连续的32个线程。

(2)warp是基本的调度单元。

(3)warp执行相同的指令。(SIMT)

(4)每个线程只能执行自己的代码路径。

(5)warp内的线程存在分歧时,warp的线程两种分支都要执行。

(6)warp间线程互不干扰。大量的warp在一起可以隐藏访存延时。

tmpDB42.png

block中thread编号:

tmp7C56.png

二维block始于theadIdx.y==0 分割为一维block,重复增长threadIdx.y

三维block始于theadIdx.z==0 分割为二维block,重复增长threadIdx.z

warp存在分支发散:

tmp175C.png

部分线程执行黄色部分,部分线程执行白色部分。(代码中的分支逻辑导致的)

CPU-GPU数据传输最小化

访存合并 Coalescing

访问global memory延时:400-800cycles 几乎是最重要的性能影响因子

tmpF013.png

按照步长访问global、memory可以通过shared memory避免。 一般步长>>18的时候,访存的开销会比较大,这是可以通过将数据加载到shared memory中进行处理。

shared memory

tmp8B54.png

shared memory关于bank的问题

tmp8FA3.png

bank0:对应地址0 地址32 地址64等,每周期只能相应一个地址。

bank conflict

tmpE744.png

下图产生了bank冲突

tmp274B.png

tmpF674.png

所有线程读取同一个地址的时候,通过广播机制不会发生bank confict,只有同时访问一个bank的时候才会发生冲突。

举例:矩阵转置

tmpEB5F.png

tmpF8F8.png

tmp994F.png

tmpB1BC.png

tmp5CCA.png

问题:shared memory的矩阵转置中,bank conflict是如何发生的?

CUDA的Texture纹理

tmpAB9A.png

tmp6CB4.png

tmpB80.png

tmpB742.png

tmp8E5A.png

image.png

SM资源分割

tmp81A0.png

tmp85F.png

block的数量首先于硬件配置,每个block的线程越多,由于一个SM的ALU有限,最多容纳有限数量的线程,每个block分的线程越多,那么blockd的数量就会变小。这种变化有点离散。

performance cliff:增加资源用量后导致并行性急速下降

Kernel 执行配置

Grid Size试探法 (1)软件的block数大于等于SM的个数 保证都在执行一个block (2) 每个SM上的block数量应该大于2 保证多个blocks可以在SM上并发执行 如果一个block在等待同步,启动另一个block (3) 每个SM上的block数量大于100 对支持未来的设备拥有很好的伸缩性

块大小的设置 (1)块大小必须是32的倍数 (2)需要尽量多的warp尽可能地隐藏延时 (3)最少:64,通常采用128 or 256.视程序而定。 (4)也依赖于问题本身,多实验。

Latency Hiding 延时隐藏

关键点: 指令按顺序发布 一个线程的任一操作数没有预备好时将阻塞等待 延时在切换线程时被隐藏 总的来说就是需要多一些线程来隐藏延时

Occupancy 占用率

定义:一个SM里面激活的warp与最大可容纳的warp数目的比值 最大warp数目:32inTesla 48 in Fermi ??(ampere?)

tmp4A02.png

假设一个指令需要2个时钟周期。

tmp28BC.png

26 / 48(SM最多驻留48个warp) ≈ 54%

tmp5FFB.png

数据预读 Data Prefecthing

tmp36F3.png

指令优化

tmp2B4F.png

tmp9CD2.png

循环展开

不用循环 用手写

tmp8FC.png

tmp895C.png

编译器自动实现循环展开

tmp788B.png

循环展开的缺点: