原文链接

第八节:利用CUDA函数库

Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员。他在多个国家级的实验室进行大型并行运算的研究,并且是几个新创企业的合伙人。大家可以发邮件到rmfarber@gmail.com与他沟通和交流。

在关于CUDA(Compute Unified Device Architecture,即计算统一设备架构的简称)的系列文章的第七节,我探讨了下一代的CUDA硬件。在本小节,我的关注重点略有转移,从硬件转到了软件,注重于CUDA函数库。

优化库提供了一种快捷的方法改进应用程序的性能。当为大型遗产项目建立端口时,函数库可能是建立新平台的唯一真实有效的优化方式,因为代码改变会要求大量的验证工作。实际上,函数库很方便,可以极大地促进代码的发展和应用程序的性能,但是不能盲目地利用代码。以GPU为基础的函数库特别要求你仔细考虑数据布局以及如何使用函数库.否则,你就可能得到极不理想的性能。

Basic Linear Algebra Subprograms (基本线性代数子程序BLAS)包实际上是基本线性代数运算(如向量和矩阵相乘)的编程界面。NVIDIA 利用其GPU函数库(也就是CUBLAS)对这个界面提供支持。CUFFT是NVIDIA支持的另外一个函数库,基于GPU执行快速傅立叶变换(Fast Fourier Transform ,FFT), 这是在科学和信号处理应用程序中最常用的一个方法。它仿照了FFTW高度优化,用于广泛目的处理器上的,颇受用户喜欢的FFT包。

BLAS 根据以下三个不同等级构架:

等级1  算法式的样例,包括提取两个向量的内部产品,或用常量乘子增加向量;

等级2  算法式为矩阵向量乘或单右侧三角解方程组;

等级3  算法式包括密集矩阵向量乘

如果我们假定向量为长度N或矩阵N*N, 然后等级1算法式,等级2算法式和等级3算法式的浮点运算的数分别为O(N), O(N2),和O(N3)。(Big-O标识是描述输入大小如何影响算法消费计算资源的(如时间或内存)一个便捷的方法)。

应用程序使用CUBLAS函数库的基本模式就是:在GPU内存空间创建矩阵和向量目标,用数据填满目标,调用一系列CUBLAS函数,最后,将结果从GPU内存空间转移到主机。为此,CUBLAS提供帮助函数,以创建和摧毁GPU空间里的目标,将数据写入这些目标,或从这些目标检索数据。CUBLAS使用行为主存储和基于1的索引,以获得最大的FORTRAN兼容性。C和C++ 应用程序需要使用宏观或行内行数以促进对CUBLAS创建的目标的访问。

当使用CUBLAS(和BLAS例程)时,数据移动是一个中心考虑点。根据不同等级,BLAS数据移动为O(N), O(N2), 和 O(N2),这样,每个移动的数据项的浮动点运算数为O(1), O(1), 和O(N)。这意味着确定数据在GPU上的位置非常重要,我将会更详细地讨论这个问题。

因为GPU的线程处理器仅在GPU本地数据上运行,主机的内存空间上的向量或矩阵的BLAS运算需要数据转移操作。相对于图形处理器的浮点能力来说,这些数据转移比较昂贵(GPU执行浮点的速度可比移动数据快)。只要有可能,就要尽量避免数据转移,它们也可能给成为获得高性能的瓶颈。

为了描述清楚,考虑下把一个向量从主系统转移到GPU所需花费,用一个常量相乘,然后将结果返回给主机。这个“应用程序”要求从GPU来回移动4N字节数据(N是向量内浮点的数量)以进行N次相乘(常量的向量倍)。

这个“应用程序”执行的最好结果是:用8除以传输带宽(所要求的字节数,以将32位浮点移动离开或进入GPU)。“幸运”的话,假定主机和GPU之间是4GB/秒的传输速度,这样的一个应用程序会得到a = GFLOP (每秒十亿浮点运算billion floating-pointoperations per second)浮点性能。这正好低于最经济的低端NVIDA GPU的浮点性能。充分利用PCIebus的全双工能力,分批多次操作可加强这一性能。

底线:如果要等级1和等级2BLAS应用程序发挥最好的性能,要求在GPU上保存尽可能多的性能。如果不可能,至少要尝试分批次尽可能进行库调用。

等级3BLAS应用程序可获得非常有效的性能。表1说明了不同构架上的SGEMM基准(如,HP xw8600配备Xeon E5440,速率2.83GHz,运行CUDA2.0的C870和C1060)。值得注意的是:基准执行的操作次序和执行快速矩阵幂的计算金融应用程序的操作次序一致――因此,它反应了真实世界的性能能力。所有的结果都报道在GELOP里。CUBLAS命名内的"Thunking"是一个界面,会自动分配内存,复制数据到GPU,运行运算,复制回结果,然后释放内存。这样,它就成为了BLAS的替代品,但是因为数据移动关系,它有着明显的性能实质。在标识为"GPUonly"的栏目,应用程序开发人员管理数据分配/释放和拷贝。在本例中,内存被分配一次,数据被拷贝,大批SGEMM被调用,然后复制回结果。移动数据的花费很小。结果包括8和10系列上的Tesla卡上的几个N*N矩阵尺寸和一个四核CPU。请注意,相比thunking界面,对小尺寸矩阵来说,CPU要运行得快一些,但是如果应用程序开发人员更贴近地管理数据移动,GPU执行效率会更好一些。

N

CPU 单线程

CPU 2 核心

CPU 4 核心

C870 Thunking

C870 GPU 仅

C1060 Thunking

C1060 GPU 仅

512

14.92

29.84

51.14

44.75

171.29

67.13

245.12

768

14.62

28.32

53.31

75.51

172.86

90.62

332.18

1024

14.62

28.08

54.73

85.92

173.7

113.04

317.68

2048

20.48

40.06

76.71

121.01

166.72

197.5

354.96

表1

对备用NVIDIA库的这一代可以有所改进。例如,在论文LU, QR and Cholesky Factorizations using Vector Capabilities of GPUs,Vasily Volkov和James Demmel声称用他们的矩阵-矩阵乘法例行程序,可达到G80系列GPU的顶级性能。他们的论文里,详细探讨了GPU内存系统,以对特定的改进进行设计。他们声称他们的方法比CUBLAS1.1执行要快约60%。这些改进被添加入了CUBLAS2.0版本,以用来产生上列表格内所示的结果。NVIDIA一直没有停止过对硬件和库代码的改进。在GPU上用BLAS可获得优异性能。例如,FORTRAN程序员应该参考FLAGON, 它是要给开放源库项目,执行一个添加GPU“设备描述符的中间件调用层,以帮助优化性能。在他们的Supercomputing 2007 poster,Nail A. Gumerov, Ramani Duraiswami,和William D. Dorland声称,当使用迭代解算器,给分散数据配备径向基函数时,使用CUFFT和一些优秀的性能结果,可以在Intel QX6700系列CPU代码基础上提速25倍。

在各类文章里,也有很多样例,GPU库提供了一些方便,但是没有带来性能优势(有时候甚至会损坏性能)。正如之前讨论的,数据移动的成本会是决定性的因素。例如,参考CUFFT vs. FFTW,以获得对此的出色界定。

总而言之,NVIDIA CUFFT和CUBLAS库为线性代数导引和快速傅立叶提供了一个便捷和广为接受的界面。有了它们,大型项目可以使用图形处理器。如果注意最小化或者消除数据移动,可以获得出色的性能。分批多次进行库调用可增加性能。对CUDA启动的设备的特点予以关注,可以获得改进。因为NVIDIA正在持续改进硬件和库代码,让我们期待持续的性能进步吧。

CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第八节的更多相关文章

  1. CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第七节

    第七节:使用下一代CUDA硬件,快乐加速度 原文链接 Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多个 ...

  2. CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第一节

    原文链接 第一节 CUDA 让你可以一边使用熟悉的编程概念,一边开发可在GPU上运行的软件. Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Lab ...

  3. CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第六节

    原文链接 第六节:全局内存和CUDA RPOFILER  Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在 ...

  4. CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第四节

    了解和使用共享内存(1) Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多个国家级的实验室进行大型并行运 ...

  5. CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第二节

    原文链接 第二节:第一个内核 Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多个国家级的实验室进行大型并 ...

  6. CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第十节

    原文链接 第十节:CUDPP, 强大的数据平行CUDA库Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多 ...

  7. CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第九节

    原文链接 第九节:使用CUDA拓展高等级语言 Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多个国家级的 ...

  8. CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第五节

    原文链接 第五节:了解和使用共享内存(2) Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多个国家级的实 ...

  9. CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第三节

    原文链接 第三节:错误处理和全局内存性能局限 恭喜!通过对CUDA(Compute Unified DeviceArchitecture,即计算统一设备架构的首字母缩写)系列文章第一节和第二节,您现在 ...

随机推荐

  1. 简谈react中的虚拟DOM

    相信你在看到此篇前也翻阅大量的对DOM的文章讲解和介绍 react中的虚拟DOM 此篇我尽量说人话(大白话),不然想必你在看到别的大神的文章早就懂了. 不说废话了,上干货. 1.首先简单对Html中的 ...

  2. Java:基本语法

    Java语言是由类和对象组成的,其对象和类又是由变量和方法组成,而方法,又包含了语句和表达式. 1. 变量 Java语言提供了两种变量:成员变量和局部变量 成员变量:是在方法体外的类中声明和定义的,可 ...

  3. 架构师分享 Docker 新手入门完全指南

    来源:架构师小秘圈 ID:seexmq Docker 最初 dotCloud 公司内部的一个业余项目 Docker 基于 Go 语言 Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案 Do ...

  4. [AHOI2009]飞行棋 BZOJ1800

    题目描述 给出圆周上的若干个点,已知点与点之间的弧长,其值均为正整数,并依圆周顺序排列. 请找出这些点中有没有可以围成矩形的,并希望在最短时间内找出所有不重复矩形. 输入输出格式 输入格式: 第一行为 ...

  5. 08.Spring Bean 解析 - BeanDefinitionDocumentReader

    基本概念 BeanDefinitionDocumentReader ,该类的作用有两个,完成 BeanDefinition 的解析和注册 . 解析:其实是解析 Ddocument 的内容并将其添加到  ...

  6. Sorted Subsegments

    https://www.hackerrank.com/contests/101hack38/challenges/sorted-subsegments/problem 首先要注意到可以二分答案,比如当 ...

  7. 【转】《Unity Shader入门精要》冯乐乐著 书中彩图

    为方便个人手机学习时候查阅,从网上转来这些彩图. 如属过当行为,联系本人删除. 勘错表 http://candycat1992.github.io/unity_shaders_book/unity_s ...

  8. C# 几种数据类型转换方式

    1.(int)变量名[强制类型转换] 该转换方式主要用于数字类型之间的转换,从int类型向long,float,double,decimal 类型转换可以使用隐式转换,但从long型到int 就需要使 ...

  9. IE浏览器与非IE浏览器JS日期兼容性问题处理

    执行语句 console.log(new Date("2017-07-04 18:40").getTime()); 在IE浏览器中打印出:NAN 在非IE浏览器中打印出:14991 ...

  10. android 开发AlertDialog.builder对话框的实现

    AndroidAPI提供了Dialog对话框控件,但google明确指出不建议开发者只是使用Dialog来创建对话框,而应该自定义对话框或者使用API中提供的Dialog的子类,如AlertDialo ...