文章目录

  • 前言
  • 存取效率
  • 计算效率
  • 性能优化要点
    • 展现足够的并行性
    • 优化内存访问
    • 优化指令执行

前言


  CUDA算法的效率总的来说,由存取效率和计算效率两类决定,一个好的CUDA算法必定会让两类效率都达到最优化,而其中任一类效率成为瓶颈,都会让算法的性能大打折扣。

存取效率


  存取效率即GPU和显存之间的数据交换效率,在上一篇博客中,我们介绍了GPU的存储结构,对GPU的各类存储介质有了一个初步的了解,其中全局内存具有最大的容量和最慢的访问效率,且对是否对齐和连续访问很敏感,这也是我们在前面推荐进行内存对齐的原因;共享内存访问速度快,且对是否对齐和连续访问不敏感,但是对Bank Conflict非常敏感,Bank Conflict的影响本文在后面会详细介绍,灵活使用共享内存会获得很高的存取效率,也是众多优秀CUDA算法替代全局内存的不二选择;寄存器具有最快的访问速度,只对每个线程可见,线程内多使用寄存器是良好的习惯,但是需要注意一个SM内的寄存器数量有限,当单个线程的寄存器数量超过限制,会影响线程的实际占用率,从而影响加速效果;其他存储介质如纹理内存常量内存等较共享内存和寄存器,在速度并没有太大优势,但是其具有的一些特殊特性使其有时候在特定的情况下被使用以获得更高的效率,比如纹理内存带有的纹理缓存具备硬件插值特性,可以实现最邻近插值和线性插值,且针对二维空间的局部性访问进行了优化,所以通过纹理缓存访问二维矩阵的邻域会获得加速,这个特性使得纹理内存在一些图像处理算法中具有一定的优势。

计算效率


  计算效率就是指除去内存交换过程以外的算法计算部分的效率,GPU中主要有三类基础运算:整数运算、单精度浮点数运算和双精度浮点数运算,其中单精度浮点运算速度最快而双精度浮点运算速度最慢,FLOPS(floating-point operations per second, 每秒执行的浮点运算次数)也是衡量GPU运算性能的关键指标,如果一个程序内只有单精度浮点数运算,将发挥硬件的最大功效,因此应该尽量多使用单精度浮点数运算,而避免使用双精度浮点运算。实际上,GPU的单核运算性能远不及CPU,因为单核运算速度取决于核心频率,而GPU的核心频率远不及CPU,目前主流的英特尔第七代桌面级CPU的核心频率都在3.5~4GHz左右,并支持超频,而NVIDIA在2016年发布的号称地球最快显卡NVIDIA TITAN X的核心频率也不过是1.4GHz,和CPU差距依然较大。但是GPU的核心数是CPU所完全无法比拟的,其并行计算效率一般情况下远远大于CPU的单核甚至多核计算效率,核心数的优势让GPU的浮点运算效率远高于CPU,所以对GPU程序来说,让GPU利用率达到100%,让每个线程都处于活动状态,对提高程序的性能有着至关重要的作用。此外,在提高CPU利用率的同时,还必须关注另一个因素:分支(if、else、for、while、do、switch等语句)对计算效率的影响,由于硬件每次只能为一个线程束获取一条指令,若线程束中一半的线程要执行条件为真的代码段,一半线程要执行条件为假的代码段,这时有一半的线程会被阻塞,而另一半线程会执行满足条件的那个分支,如此,硬件的利用率只达到了50%,大大影响并行性能。

性能优化要点


  在基于CUDA优化算法设计过程中,除了使算法能够运行得到正确结果之外,更重要的是算法效率能达到理想的水平,而从上面的描述来看,要发挥CUDA算法的性能优势必须考虑全面,留意一些性能陷阱,采用合理的算法设计方案。一般来说,优化一个CUDA算法的性能需要专注三个方面,按照重要性排序为:

展现足够的并行性

  为了最大程度的利用GPU多线程的优势,应该在GPU上安排尽量多的并发任务,以使指令带宽和内存带宽都达到饱和,在一个SM(流处理器)中保证有足够多的并发线程束,这不单单是要为GPU每个线程都安排任务,还需要检查SM资源占用率的限制因素(共享内存、寄存器以及计算周期等)以找到达到最佳性能的平衡点,因为GPU的内存资源是有限的,为每个线程分配的资源也是有限的,如果算法设计者在一个线程中使用了过多的共享内存或者寄存器,那么并发运行的线程数必然会减少,使得SM资源的实际占用率小于理论占用率;另一方面可以为每个线程/线程束分配更多独立的工作。

优化内存访问

  大部分GPU算法的性能瓶颈都在于内存访问速度,由于显存访问的高延迟和低效率,内存访问模式对内核性能有着显著的影响。内存访问优化的目标是最大限度地提高内存带宽的利用率,重点在于优化内存访问模式和保证充足的并发内存访问。在GPU中,线程是以线程束为单位执行的,一个线程束包含32个线程,所以一方面我们最好将并发线程数设置为32的倍数,另一方面当一个线程束发送内存请求(加载或存储)时,都是32个线程一起访问一个设备内存块,因此对于全局内存来说,最好的访问模式就是对齐和合并访问,对齐内存访问要求所需的设备内存的第一个地址是32字节的倍数,合并内存访问指的是通过线程束中的32个线程来访问一个连续的内存块。这表示在算法设计中一定要尽量为一个线程束的线程分配连续的内存块,比如0~31号线程(同一个线程束)访问影像中连续存储的31个像素,而不是访问不连续的31个像素,由于合并访问对内存访问效率影像非常大,所以我们在算法设计中建议严格遵守该要求。

  共享内存因为是片上内存,所以比本地和设备的全局内存具有更高的带宽和更低的延迟,使用共享内存有两个主要原因:①减少全局内存的访问次数;②通过重新安排数据布局避免未合并的全局内存的访问。在物理角度上,共享内存通过一种线性方式排列,通过32个存储体(bank)进行访问。Fermi和Kepler架构各有不同的默认存储体模式:4字节存储体模式和8字节存储体模式,共享内存地址到存储体的映射关系随着访问模式的不同而不同,当线程束中的多个线程在同一存储体中访问不同字节时,会发生存储体冲突(Bank Conflict),由于共享内存重复请求,所以多路存储体冲突可能要付出很大的代价,应该尽量避免存储体冲突,每个存储体(Bank)每个周期只能指向一次操作(一个32bit 的整数或者一个单精度的浮点型数据),一次读或者一次写,也就是说每个存储体(Bank)的带宽为每周期 32bit,比如一个32*32的二维单精度浮点数组,每一列属于一个Bank,如果一个线程束里的不同线程访问该数组里同一列的不同数据,则会发生Bank Conflict,解决或减少存储体冲突的一个非常简单有效的方法是填充数组,在合适的位置添加填充字,可以使其跨不同存储体进行访问,从而减少延迟并提高了吞吐量。

  寄存器是GPU上最快的存储机制,但是数量非常有限,如果一个线程使用过多的寄存器,会导致SM能够同时启动的线程数变少,实际上很多情况下寄存器都成为了资源占用率无法达到100%的主要限制条件,所以往往要注意监控寄存器的数量,当数量没有超标时,适当的增加数量可以提升性能,而一旦数量超标,最好还是将寄存器的数量减少以保证100%的资源占用率,这可以通过重新排列代码的顺序来实现,比如当变量的赋值和使用靠的很近时,编译器会重复使用少量寄存器以达到减少寄存器数量的目的。

优化指令执行

  GPU属于单指令多数据流架构,每个线程束中的所有线程在每一步都执行相同的指令,如果每个指令都能够得到对结果有效的运算值,就能够避免线程的浪费,而如果由于条件分支造成线程束内有不同的控制流路径,则线程运行可能出现分化,这时线程束必须顺序执行每个分支路径,并禁用不在此执行路径上的线程,而如果算法的大部分时间都耗在分支代码中,必然显著的影响内核性能,所以尽量避免使用分支是很关键的,或者尽量使分支有非常大的概率执行对结果有效的哪一个路径。

【遇见CUDA】CUDA算法效率提升关键点概述相关推荐

  1. CUDA并行计算 | CUDA算法效率提升关键点概述

    文章目录 前言 存取效率 计算效率 性能优化要点 展现足够的并行性 优化内存访问 优化指令执行 前言   CUDA算法的效率总的来说,由存取效率和计算效率两类决定,一个好的CUDA算法必定会让两类效率 ...

  2. MIT新研究:过去80年,算法效率提升到底有多快?

    来源:MIT,新智元 编辑:David [导读]随着摩尔定律走向终结,靠提升计算机硬件性能可能越发难以满足海量计算的需要,未来的解决之道在于提升算法的效率.MIT的这篇新论文总结了过去80年来,算法效 ...

  3. AI算法效率每16个月提速一倍,算力革命超越摩尔定律

    AI算法效率每16个月提速一倍,算力革命超越摩尔定律 2020-05-06 22:10:26 作者 | 蒋宝尚 编辑 | 丛 末 摩尔定律预测芯片性能每18个月翻一倍,那 AI 算法性能多少个月翻一番 ...

  4. 超摩尔定律!OpenAI官宣AI算法效率每16个月翻一番

    OpenAI今天宣布将开始追踪机器学习模型的效率,并对AI算法演进的情况进行定量追踪,结果显示算法改进效率吊打摩尔定律. 为了启动这一进程,Open AI发表了一份分析报告,开篇即用数据展示了算法演进 ...

  5. Nvidia CUDA初级教程2 并行程序设计概述

    Nvidia CUDA初级教程2 并行程序设计概述 视频:https://www.bilibili.com/video/BV1kx411m7Fk?p=3 讲师:周斌 本节内容: 为什么需要? 怎么做? ...

  6. 轻松上手UAI-Train,拍拍贷人脸识别算法优化效率提升85.7%

    2019独角兽企业重金招聘Python工程师标准>>> "UAI-Train平台可以让我们方便地在短时内使用大量的GPU资源,用较低的成本训练海量的数据集,提高算法模型迭代 ...

  7. 我在京东做研发丨京东物流仓储效率提升AI算法大揭秘

    在京东无人仓内 十几种不同的机器人自动完成订单生产和商品入库.拣选 同时还有操控全局的智能控制系统 实现仓库自动治理.控制.决策 仓储运营效率大大提升 本期,京东云邀请京东物流通用AI算法专家将为你揭 ...

  8. 效率提升3倍的Paper阅读方法

    视频链接:https://www.bilibili.com/video/BV1Q4411R7cY 效率提升3倍的Paper阅读方法 1 为什么要读论文 构建知识体系 紧跟前沿技术 培养科研逻辑 写论文 ...

  9. 电商直播平台如何借助容器与中间件实现研发效率提升100%?

    作者:鹿玄,阿里云解决方案架构师 前言 直播带货是近期发展非常迅猛的一种新的电商模式.构建一个电商直播平台从技术角度上大致可以分为视频直播服务.CDN.前端(H5/ 小程序).大数据.以及各种业务后台 ...

最新文章

  1. lodash(一)数组
  2. LoaderManager使用详解(三)---实现Loaders
  3. 记录一个班级的成绩练习一维数组
  4. ABAP Development Tool后台处理前台请求的入口
  5. 在Word XP中也能插入国际音标、拼音
  6. CC254x--API
  7. python的flask实现第三方登录怎么写_Python语言的Flask框架应用程序实现使用QQ账号登录的方法...
  8. java 开关按钮_Java Swing JToggleButton开关按钮的实现
  9. 生成和解析二维码(zxing)
  10. python-numpy.array中,any()和all()方法介绍
  11. oracle必须配置哪个参数,oracle – 此操作必须将ORA-02069 global_names参数设置为TRUE...
  12. 学成在线案例(完整代码)
  13. 数据预处理transforms
  14. 3.7 App.vue-常用配置【uni-app教程uniapp教程(黄菊华-跨平台开发系列教程)】
  15. 学习笔记(13):21天通关Python(视频课)-字典高级用法
  16. maya安装步骤 新手安装软件基础教程(附安装包)
  17. 加速度速度位移的计算
  18. 排球比赛计分程序的典型用户和场景
  19. cesium实现四色预警(仿echarts)(cesium篇.50)
  20. uniapp 消息推送与透传+语音播报

热门文章

  1. CorelDRAW破解版是如何一步一步坑人的
  2. aspiration搭配_明3你们最喜欢的组合有哪些?
  3. 借win11 WSA升级12l,水一贴升级方法和说说要不要升级win11。
  4. Gamma、Linear、sRGB 和Unity Color Space,你真懂了吗?
  5. Docker基本使用教程
  6. Internet Download Manager v6.41.3中文特别版IDM下载器免费下载
  7. LoRA转4G及网关中继器工作原理
  8. 购物车(session版)
  9. spark编程基础python版实验报告_Spark编程基础(Python版)
  10. 一篇文章让你掌握HTML+CSS