六 GPU 并行优化的几种典型策略
前言
如何对现有的程序进行并行优化,是 GPU 并行编程技术最为关注的实际问题。本文将提供几种优化的思路,为程序并行优化指明道路方向。
优化前准备
首先,要明确优化的目标 - 是要将程序提速 2 倍?还是 10 倍?100倍?也许你会不假思索的说当然是提升越高越好。
但这里存在一个优化成本的问题。在同样的技术水平硬件水平下,提升 2 倍也许只要一个下午的工作量,但提高 10 倍可能要考虑到更多的东西,也许是一周的工作量。提高 100 倍, 1000 倍需要的成本,时间就更多了。
然后,需要将这个问题进行分解。通常来说先对数据集进行分解,然后将任务进行分解。这里要从数据集这样的矩阵角度来分析数据,将输入集和输出集中各个格点的对应关系找出来,然后分派给各个块,各个线程。
策略一:识别代码中的瓶颈所在
分析程序效率的瓶颈所在一方面靠的是分析。这种方式对于代码结构比较简单的程序非常有用,但对于实际应用中的复杂项目,人脑分析往往会导致错误的结论 - 也许你费尽心思想出来了瓶颈,然后对它做了优化,之后却发现效率仅仅提升了 1%。
因此更有效的方法是使用分析工具来找出瓶颈,可以使用 CUDA Profiler 或者 Parallel Nsight。
使用 Parallel Nsight 分析并行程序的方法请参考我的这篇文章:(准备中...)
还有一点要特别说明的是,在 GPU 进行数据处理的时候,CPU 可以考虑做点别的事情,比如去服务器取数之类的,这样就将 CPU 并行和 GPU 并行结合起来了,程序效率自然会大大提高。
策略二:合理的利用内存
首先,要灵活的使用显卡中的各类内存结构,如共享内存,常量内存等。特别要注意共享内存的使用,它的速度可是接近一级缓存的。
此外,必要时对多个内核函数进行融合。因为这样可以避免启动新的内核函数时需要进行的数据传递问题,还可以重用前面的任务遗留下的一些有用的数据。不过,如果是对别人写的多个内核函数进行融合的话,一定要注意其中隐含的同步问题 - 上个内核函数的代码彻底执行完毕之后,下个内核函数才会开始执行。
然后,对于数据的访问应该采取合并访问的方式 - 尽量使用 cudaMalloc 函数。一次访问的数据应当大于 128 字节,这样才能充分地利用显卡的带宽。
策略三:传输过程的优化
前面的文章已经提到过很多次了,数据在内存和显存之间进行交换是非常费时的。
对于这样的问题,首先我们可以以锁页内存的方式使用主机端内存。所谓锁页内存,是指该区域内存和显卡的传递不需要 CPU 来干预,如果某区域不声明为锁页内存,那么在内存往显存中或者显存往内存中传递数据前,会发生一些开销不小的锁定操作(表示该区域内存正在和显存发生数据传递,CPU勿扰)。
使用方法是调用 cudaHostAlloc 函数。这个函数的功能不单单是声明锁页内存那么简单。通过设置函数的参数,该函数还能实现很多非常实用的功能,个人非常推荐。
然后,还需要重点推荐的是零复制内存。它是一种特殊的锁页内存,一种特殊的内存映射。它允许你将主机内存映射到 GPU 的内存空间。如果你的程序是计算密集型的,那么这个机制就会非常有用,它会自动将数据传输和计算重叠。具体用法请参考我的这 篇文章。
策略四:线程结构布局的优化
建立科学的计算网格,通过设定合适的维数,块数,以及块内线程数来尽量实现合并的内存访问,保证最大的内存带宽。
要学会灵活使用多维度的计算网格,而不是仅仅局限于一维。多维计算网格的使用请参考我的这篇文章。
尤其在单维度的块数受到限制的时候,多维网格就必须被考虑进来了。
策略五:从算法本身进行任务级的分解
将算法的步骤分解各个不相关的部分,步骤内采用GPU并行,这几个步骤则采用CPU并行。
策略六:灵活使用 CUDA C 的一些库还有 API
CUDA C 提供了很多实用的 API,且提供相当多的C++支持 (非全部)。能大大地提高开发效率。如原子操作函数等等,很方便。
CUDA 提供了许多实用的库:如 cuBlas cuSparse等,不在此一一介绍。尤其是 Thrust 库,简直就是 STL 的并行实现,拿来直接用非常方便。
小结
优化思路可以说是 CUDA 并行编程最为核心,也是最为关键所在。
本文仅仅是提供优化的总体策略和思路,至于具体的实现方法,请参考相关资料实现之。
六 GPU 并行优化的几种典型策略的更多相关文章
- 第六篇:GPU 并行优化的几种典型策略
前言 如何对现有的程序进行并行优化,是 GPU 并行编程技术最为关注的实际问题.本文将提供几种优化的思路,为程序并行优化指明道路方向. 优化前准备 首先,要明确优化的目标 - 是要将程序提速 2 倍? ...
- 使用 CUDA 进行计算优化的两种思路
前言 本文讨论如何使用 CUDA 对代码进行并行优化,并给出不同并行思路对均值滤波的实现. 并行优化的两种思路 思路1: global 函数 在 global 函数中创建出多个块多个线程对矩阵每个元素 ...
- 第七篇:使用 CUDA 进行计算优化的两种思路
前言 本文讨论如何使用 CUDA 对代码进行并行优化,并给出不同并行思路对均值滤波的实现. 并行优化的两种思路 思路1: global 函数 在 global 函数中创建出多个块多个线程对矩阵每个元素 ...
- App架构师实践指南六之性能优化三
App架构师实践指南六之性能优化三 2018年08月02日 13:57:57 nicolelili1 阅读数:190 内存性能优化1.内存机制和原理 1.1 内存管理内存时一个基础又高深的话题,从 ...
- GPU 编程入门到精通(四)之 GPU 程序优化
博主因为工作其中的须要,開始学习 GPU 上面的编程,主要涉及到的是基于 GPU 的深度学习方面的知识,鉴于之前没有接触过 GPU 编程.因此在这里特地学习一下 GPU 上面的编程.有志同道合的小伙伴 ...
- 工程能力UP | LightGBM的调参干货教程与并行优化
这是个人在竞赛中对LGB模型进行调参的详细过程记录,主要包含下面六个步骤: 大学习率,确定估计器参数n_estimators/num_iterations/num_round/num_boost_ro ...
- [源码解析] PyTorch分布式优化器(2)----数据并行优化器
[源码解析] PyTorch分布式优化器(2)----数据并行优化器 目录 [源码解析] PyTorch分布式优化器(2)----数据并行优化器 0x00 摘要 0x01 前文回顾 0x02 DP 之 ...
- 五 浅谈CPU 并行编程和 GPU 并行编程的区别
前言 CPU 的并行编程技术,也是高性能计算中的热点,也是今后要努力学习的方向.那么它和 GPU 并行编程有何区别呢? 本文将做出详细的对比,分析各自的特点,为将来深入学习 CPU 并行编程技术打下铺 ...
- GPU 编程入门到精通(五)之 GPU 程序优化进阶
博主因为工作其中的须要,開始学习 GPU 上面的编程,主要涉及到的是基于 GPU 的深度学习方面的知识.鉴于之前没有接触过 GPU 编程.因此在这里特地学习一下 GPU 上面的编程. 有志同道合的小伙 ...
随机推荐
- Web API系列
ASP.NET Web API 是一种框架,用于轻松构建可以访问多种客户端(包括浏览器和移动设备)的 HTTP 服务. ASP.NET Web API 是一种用于在 .NET Framework 上构 ...
- select2 插件
官网:http://select2.github.io/ Select2是基于jQuery的一个插件,没有引用jQuery,是没有效果的 1.在实现给select2添加placeholder效果的 ...
- [转载]Matrix类的使用
2013-12-18 11:31:00 转载自: http://www.cnblogs.com/mmy0925/archive/2013/01/22/2871009.html 在Android中,对图 ...
- Spring框架及IOC容器
Spring是一个非常活跃的开源框架, 它是一个基于IOC和AOP来构架多层JavaEE系统的框架,它的主要目地是简化企业开发.Spring以一种非侵入式的方式来管理你的代码, Spring提倡”最少 ...
- 解决使用OCI连接oracle LNK2019: 无法解析的外部符号的问题
据我所知,在使用OCI连接Oracle时出现LNK2019: 无法解析的外部符号问题的情况有两种: 一.没有引入附加依赖项,右键项目->属性->配置属性->链接器->输入中添加 ...
- 【转】./configure && make && make install详解
在Linux中利用源码包安装软件最重要的就是要仔细阅读安装包当中的README INSTALL两个说明文件,这两个文件会清楚的告诉你如何可以正确的完成这个软件的安装! 我们都知道源 ...
- mysql 导入数据库文件到指定数据库
i:\mysql\bin>mysql -u 用户名 -p 数据库名 < i:/test.sql // (source "c:\adsense.sql" ) ...
- SharePoint表单和工作流 - Nintex篇(二)
博客地址 http://blog.csdn.net/foxdave 接上篇点击打开链接 试用版获得的示例网站是一个SharePoint 2010 Server版的网站,我们先来看一下Nintex整个一 ...
- sql 之CONCAT用法
这是java交流群里一个网友面试的时候发过来的笔试题,我觉得题目的假定条件应该是某个字母对应的最小数字只有一个. 思路第一步是查出一个子表s1: select name,min(number) fro ...
- hadoop版本和位数的查看方法
目前针对apache hadoop更新的版本较多,由此而产生了两个方面的问题: 1.如何查看运行的集群当中的hadoop的版本的问题. 2.如何查看运行集群当中的hadoop的位数 下面详细的介绍一下 ...