GPU优化方法总结

GPU优化方法总结

一.内存访问

A.片上

a.使用专用内存(存储重用的数据)

1.纹理内存:二维空间局部性的访问进行了优化
2.常量内存:数据广播给多个线程只会产生一次内存事务
3.共享内存:
  * 填充、重新排序数据或重新映射线程到数据
  * 编写分配工具,将线程与数据配对
  * 同步导致的stall,可以减少线程块大小

b.使用warp函数,如shuffle函数

c.寄存器分块(时间分块):时间维度的重用

e.减少寄存器使用:

1.使用指针
2.最小化临时变量
3.临时变量移至共享内存
4.将小类型打包成大类型
5.避免存储可重新计算的值
6.展开循环也可以节省寄存器
7.改变算法
8.强制编译器限制寄存器使用(maxrregcount)
9.或者更激进地编写自定义寄存器分配器

f.重新算(避免通信,减少对全局内存的访问次数和读取的数据量)

B.片外

a.合并访问

1.重组线程
2.选择一个好的线程块大小
3.分块
4.择不同的并行化策略
5.执行复杂的索引操作
6.数据从全局内存以合并的方式加载到共享内存
7.调整全局内存中的布局
  * 结构体数组转换为数组的结构体
  * 行主序数组切换到列主序数组
  * 填充
8.对昂贵的随机访问加载进行缓存
9.针对合并访问,设计一种新的存储格式

b.空间分块

1.自动调优:选择最优的线程块维度
2.块的维度与线程块的维度解耦.方便调整线程块的工作量

c.Kernel融合

1.二个Kernel使用相同的全局内存时,可减少对全局内存的访问
2.提高缓存利用效率、增强数据局部性和重复使用
3.减少内核启动开销
4.弊端:融合后的内核可能需要更多寄存器和共享内存

d.预取(解决延迟问题,软件流水线)

1.双缓冲
2.不同的warp扮演不同的角色

e.数据压缩(缓解容量和带宽问题)

1.稀疏矩阵

f.预计算

1.离线执行计算,在Kernel里重用该数据

g.使用宽加载指令

二.如何高效地将不规则算法映射到GPU上

a.循环展开:

1.减少与循环相关的指令
2.增加指令级并行性(ILP)的机会
3.数组存储在寄存器中
4.消除循环相关的分支
5.指令的向量化
6.过大的展开因子可能会影响性能

b.降低分支分歧(可能会受到算法设计的很大影响)

1.如果分支中的指令足够简单,分支可以被替换为有条件的指令
2.完全移除分支
3.用算术指令替换分支
4.算法扁平化
5.查找表
6.内核分裂
7.通知线程已完成的工作来减少分支
8.循环展开
9.延迟执行
10.将代码移动到分支外部
11.简化指令以实现指令的有条件执行
12.数据布局的变化(填充或引入稀疏格式)

c.使用稀疏矩阵格式

d.内核分裂(简化和增加内核的规则性来更好地利用资源)

1.将单一的内核分为多个内核
2.单个内核的迭代过程拆分成多次迭代的过程

e.减少冗余工作(避免执行被视为冗余的工作)

三.平衡

a.指令流平衡(向量化)

1.使用向量而非标量变量
2.同时应用于向量所有元素的指令来操作这些向量

b.快速数学函数(近似数学函数)

c.以Warp为中心的编程(降低同步开销)

1.代码结构围绕warp作为计算单元的概念
2.工作不是分配给线程或线程块而是分配给warp
3.负载均衡\隐藏延迟\不同的warp执行不同的工作

d.调整每个线程的工作量

1.可以增加数据重用
2.将增加寄存器和共享内存的使用
3.最优的每线程工作量通常难以确定
   * 将数据分成小的矩形块,使得每个线程块处理更大的数据块,增加了每个线程的工作量。
   * 减少循环次数和增加每次迭代所处理的数据量,使得每个线程能够处理更多的数据。
   * 合并多个线程块或线程,将其分配给更强或更大的线程,达到更高的工作效率。
   * 将多个工作项合并为一项任务,减少调度的开销,提高并行性的利用效率。
   * 增加线程或线程块的计算量,从而有效减少执行中涉及的调度开销。
   * 通过将多个线程块合并,以更大单位来处理数据,减少全局内存访问延迟。

e.调整线程块大小

1.它影响寄存器使用、每个SM上的线程块数量、遇到barrier时保持计算单元忙碌的能力
2.自动调优(因为它易于更改,但又难以推理和找到)

f.自动调优

1.对稀疏格式的参数进行调优
2.基于矩阵的稀疏性进行调优
3.结合建模和基准测试
4.基于机器学习
5.CLTune、PADL、Kernel Tuner、OpenTuner以及提供运行和调优内核API的Kernel Tuning Toolkit
6.性能可移植性(不同硬件平台上,应用程序或算法能够保持相对一致的性能表现)

g.负载均衡

1.warps内部的负载均衡(某些线程没有执行有用的工作)
2.线程块内部的负载均衡
  * 利用全局工作列表
  * 共享内存捐赠
  * 排序数据
3.线程块之间的负载均衡通
  * 工作窃取和捐赠机制:这种机制允许在工作负载过大的情况下,线程块可以在不同的流式多处理器之间转移任务,以保持 GPU 的高效运行。
4.GPU与CPU之间的负载均衡
  * 预先静态划分的方式,将一定比例的工作负载分配到 GPU 上,其余由 CPU 处理。
  * 根据当前的工作负载情况实时调整任务分配,以提高资源使用效率。

h.减少同步(特别是当没有足够的线程隐藏barrier的延迟时)

  * 用更细粒度的原语替换barrier

i.减少原子操作

1.无锁实现
2.数据分区
3.维护数据的近似视图
4.共享内存进行原子操作或使用shuffle指令

j.跨块同步

1.原子操作
2.无锁实现
3.自定义的线程组

四.和主机交互

a.主机通信

1.彻底消除通信,即在GPU上执行所有或尽可能多的算法,或尽可能多的数据保留在GPU
2.对要通过PCI-e总线传输的数据进行压缩
3.动态并行
4.使用pinned memory, pinned and/or mapped memory for overlapping with computations
5.使用streams or command queues
6.应用双缓冲甚至三缓冲
7.压缩数据技术
8.内核分裂也可以帮助分离内核,以便可以重叠数据传输

b.CPU/GPU计算(CPU和GPU之间分割计算,利用两个设备执行有用的工作)

1.CPU预计算
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hi20240217

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值