服务器 频道

新趋势:GPU如何推动HPC向前发展

   【IT168 专稿】曾经,CPU厂商之间的竞争,几乎就是主频的竞争。各个厂商争相推出主频更高的产品以期占领市场。可是近年,所有厂商的CPU主频提升,都遇到了技术瓶颈,CPU主频高低的战争也就此偃旗息鼓。目前,我们已经很难在市场上看到高主频的CPU产品。虽然CPU主频提升的脚步就此打住,但是摩尔定律依旧生效,CPU的计算能力依旧以原有的速度在提升。现阶段CPU计算能力的持续提升,主要是得益于制造工艺的进步。现在,每个CPU可以集成更多的晶体管,而更多的晶体管也给了厂商充足的余地,来增加CPU内核数量和缓存容量,我们也由此步入了多核时代。多核时代固然好,但是多核CPU也面临着众多挑战。

    首先,一些应用只能由单一内核驱动。这些应用也是可以运行在多核上——通过多个内核各自的线程、OpenMP和 MPI运行,但是最终的整体编码的性能,还只能由一个单一的内核决定。第二,内存和I/O总线的提升速度现在赶不上多核的发展速度。这也就意味着,平均每个内核的内存带宽(memory bandwidth)将减少,对多核CPU的整体性能的提升有负面影响。第三,现在我们已经步入互联网时代,随着CPU内核的增多,平均每个网络接口(network interface)也必须分摊更多的内核,这可能也将影响计算机的整体性能,或者我们至少需要性能更高的网卡才能减缓这个瓶颈。

    尽管CPU面临了诸多问题,但HPC还是非常依赖CPU。但是与此同时,我们也开始寻找可能的替代品,来完成日益增加的、复杂的IT任务。显卡上的核心元件图形处理器Graphics Processing Unit (GPU)也就进入了我们的视野。

协处理器的历史回顾

    在往下讨论之前,我们不妨简单回顾一下计算机集群的发展历史。计算机集群的兴起,主要是因为传统的HPC系统(如SMP、MPP、NUMA等)十分昂贵,而且HPC单独一台计算机的性能无论再怎么高,也还是有局限。而多年来,普通PC性能也在不断提高,这让普通PC服务器的科研计算潜力被重视。

    1994年,在美国宇航局NASA,Goddard、Tom Sterling 和Don Becker发展了被称为Beowulf的计算机理念。所谓Beowulf计划,就是通过以太网连接方式,将16台带有DX4处理器的计算机组合成了一个计算机集群系统(Computer Cluster)。特别值得一提的是,这个计算机集群采用的是廉价普通的PC配件和开源软件。这个系统的价格仅仅为5万美金,却同样实现了极高的计算能力。如此低廉的价格深深地改变了HPC领域,极大的降低了HPC的门槛。

    也正是从这个时候开始,x86硬件以其富有吸引力的性价比,开始占领市场,高速以太网也开始进入市场(开源软件和因特网这时也开始普及,但这就是另外的故事了)。话说回来,Beowulf当时是一个巨大的成功,计算机集群填补了普通PC和HPC之间的鸿沟,这个集群的趋势,直到今天仍然在延续。今天,我们还是在以低价的计算机集群,来完成高性能要求的任务。

    HPC用户对于计算机性能的追求是没有止境的,对他们而言,还有一个方法增加计算机性能——就是添加协处理器(co-processor)到计算机系统上。协处理器,主要用于计算机集群节点的计算任务,通常有以下几种协处理器可以选择:FPGA(Field Programmable Gate Arrays),或者其他特殊的协处理器如Clearspeed。当然,这种解决方案可能需要比较昂贵的成本。协处理器继续发展,后来经过数代演变,其中的一种逐渐演变成了现在的显卡。

    现代显卡之所以能够高速发展,我们还得感谢PC游戏工业的持续进步。今天的显卡普遍采用速度极高的GPU (Graphic Processing Units)作为主要计算引擎。事实上,这些GPU是可以编程的——你可以针对GPU写各种代码。今天,如果有钱,我们可以轻松购买到高端显卡。这些高端显卡,可以让我们更顺畅的在电脑上屠杀怪兽和敌人,而本质上,这代表了更高的计算能力。

    早些年,每当CPU主频提升的时候,我们都觉得很兴奋,并且总是满心期待着CPU将拥有更高的速度和能力。与此同时,GPU却十分安静,但是在HPC领域GPU一直保持着跳跃式的发展。我们可以比较一下,03-05年的奔腾4和ATI 和NVIDIA的GPU的发展态势。

    在05年中旬,GPU的性能已经达到了CPU的数倍。譬如说Intel的桌面四核产品,Core 2 extreme QX6700,其主频在2.6GHz,浮点运算峰值为50G FLOPS,而与此同时,在市场销售的NVIDIA的GPU G80,浮点运算的峰值为330G FLOPS,而ATI的Radeon HD 2900XT则拥有475 GFLOPS的浮点运算峰值。如果你用两块ATI Radeon来配合,再超一点频,那么你的浮点运算峰值将可以达到1 TFLOP!虽然显卡的功能还主要局限于图像处理,但是我们也从中看到了GPU的巨大潜力。

    话说回来,为什么GPU的性能提升如此之迅速呢?首先是商业原因,PC游戏的急剧发展,促成了数十亿美金的市场,其中就包括了不断提高的显卡需求。利益的驱动使得GPU厂商前赴后继。第二,由于GPU的计算特性,在GPU上添加晶体管,要比在CPU上容易。第三,GPU整体的更新换代速度要快于CPU,这主要由于GPU结构设计相对简单。其实,GPU的潜力非常巨大,因为GPU已经拥有更便宜的每浮点价格,协处理器出身的GPU,也开始向主处理器的地位挑战。
 

不一样的GPU

    GPU本质上与常规CPU有所区别。GPU主要是被设计用来执行图形任务,比如建立3D场景模型然后将其基于渲染的光栅化,最后显示图像。为了提升显示图像进程的效率,现代GPU的设计很着重于传输数据。光栅化过程中,各种数据由GPU和代码片段连续的处理。

    而不在光栅化的时候,例如计算的时候,GPU可以被理解为流处理器。流处理器可以接受一系列的计算密集型操作(kernel),然后将操作用于称作流stream的数据中。这里多解释一下流的概念,经 GPU存储和操作的数据被形象地比喻成流stream。总的来说,GPU一次将一个kernel用于处理一个特定的流,而由于GPU的kernel很多,因此一次可以同时处理多个流。当然kernel并不是程序的全部,也只是算法的一部分。现在有很多工作,GPU也无法完成,比如CPU可以做到的同时读写。

    现在,我们大体知道了CPU和GPU的不同。GPU的kernel处理流的算法,对于所有流都是一样的。这样,所有的kernel连接起来,就可以同时运行一系列的操作。除此以外,每个kernel也都比较独立,不会误处理同一个流。因此,总的来看,GPU流处理的潜力是巨大的,具体而言有以下几点:

*数据和任务有清晰的并行结构。
*数据流元素之间没有通讯,简化了操作。
*Kernel不能写入流。
*流元素是独立的。
*并行隐藏了memory存取。

    可能,读者对于上述概念还有点模糊,其实上述几点已经说明了GPU的高效性。如果你的程序是根据GPU流模型编写,它的确可以给你巨大的性能提升。但天下没有免费的午餐,其缺点是,你的程序也只能受困于流计算模型。

    附属/协处理器,这个也不是什么全新的概念。早在大型HPC中,就有一些专业设备称为“队列处理”(array processors),这些配件连接在HPC系统上,发挥着协处理作用。队列处理器就很像今天的显卡市场中的GPU,辅助CPU将效能发挥到最大。

    可GPU毕竟不是CPU,GPU有很多优点,但也有很多明显的缺点:

*没有堆栈
*没有整数或bit-wise操作能力
*没有分散操作(scatter operation)。(a[i] = b)
*没有reduction操作。(max, min, sum)

    GPU不具备这些基本的能力,主要是因为游戏界面显示根本不需要显卡完成这些工作。因此GPU虽然已经有了极好的并行计算能力,但是跟CPU的全面性相比还是有差距。GPU在GPGPU (General Purpose Graphic Processor Unit) 阶段的确如此。可是我们设想,如果GPU弥补了自身功能的缺陷,而又保持了并行计算的优势,那么GPU将势不可挡。
 

GPU编程

    GPU编程,现在主要有两个API接口:OpenGL和DirectX。这也意味着,你必须将编码翻译成OpenGL或者DirectX。这可不是一项轻松的工作,你必须充分了解算法和编码。就算是用了较简单的流处理概念,用GPU API写代码仍旧还是一件困难的事情。

    打个比方,我们不能写存储(memory),而只能写纹理。我们不能写计算Kernel,只能写片段程序(fragment program)。我们也不能写数据流的foreach loop,而只能写render pass。其实现在,能够透彻的理解算法和GPU代码的程序员数量并不多。因此,我们就面临了又一个问题,GPU程序员的高门槛很可能会阻碍GPU的健康发展。因此,为GPU程序员构建一个更简单的程序解决方案迫在眉睫。

    理想中的解决方案,是一种高级别的程序语言,它应该将很多GPU底层代码抽象出来,以更加简单的方式,更加友好的界面,让那些非显卡程序员也能顺利的编写程序。其实,现在也有一些这样的GPU语言,这些GPU语言主要包括了:

*Sh
*Brook
*Shallows
*CUDA (Compute Unified Device Architecture)
*RapidMind


    这些GPU语言各有不同,但它们都很类似于C或者C++,并且包含了流概念。例如,Brook就将GPU看做一个协处理器。Brook语言自己也有衍生的语言——Brooktran。Brooktran更接近Fortran,但大体上,还是基于Brook。Brook可以运行于ATI、NVIDIA的GPU,OpenGL和DirectX接口,Windows和Linux操作系统。

    说到GPU编程,最近的GPU程序平台CUDA被炒得火热。CUDA是NVIDIA创建的一个全新的GPU编程平台。在CUDA上,最关键的好处在于你可以用最通用的C语言直接编写代码。这个特点,可以让程序员专注于他想实现的功能,而编程语言不再是瓶颈。CUDA主要有以下几个扩展:

*函数类型限定
*可变类型限定
*Kernel在GPU上如何具体的工作的指示
*4个variables可以分辨来自CPU 的grid和block的维度。

    编译器nvcc会把CPU code和GPU code分开,CPU代码还需要使用传统的编译器编译,而GPU代码通过nvcc编译。

    CUDA 拥有一个run-time library,run-time library运行在CPU(主机端),可以提供访问多个GPU,并且控制这些GPU的功能。CUDA有跑在GPU之上,嵌入式的vector数据类型,还有同时跑在CPU和GPU上的Standard C Library 子集。CUDA还拥有预置的BLAS libraries (Basic Linear Algebra Subprograms平行的基本线性代数副程序),和FFT libraries(Fast Fourier Transforms快速傅里叶转换)。CUDA这些技术的优点在于,CUDA可以合并CPU和GPU的编程工作,暂时只适用于NVIDIA的 GPU。而且就像开源软件一样,CUDA是完全免费的。
 

GPU计算资源

    现在,互联网时代已经来临,编码设计者也都告别了闭门造车的时代,GPU领域也一样。现在你可以在互联网上找到很多GPU网站,有大量的报告、工具等等资源。通过这些网站,编码程序员可以直接深入了解GPU最近的发展,寻找有用的工具,通过网络,程序员可以直接得到关于GPU的一切。如果你决定编写一些代码,那么你将可以轻松的得到相关的指南,也可以很容易的在GPU论坛里与他人交流。

    你还可以得到更多的资源,其中一些资源的细节恐怕只适用于显卡生产商,不过这些资源还都是免费的。目前最大的CUDA资源库是CUDA Zone,其中有链接、文档、SDK等等。

    ATI也有GPU程序信息网站,其中有一个关于流计算的网页,让我们知道ATI在流计算方面的成果。ATI还有一个网站,专门描述当前的流计算处理器—— AMD流处理器。你也可以从ATI网站中找到CTM (Close to Metal,一个GPU硬件层上的接口)。尽管这不是一个编译器,它还是可以允许其他开发者连接别的工具到ATI GPU,或是开发其他全新的工具。

    在GPU领域,还有一个新公司,叫做RapidMind。该公司开发的技术,可以运行在普通的C++环境(编译器complier和集成电路IDE) ,IDE被嵌入到了应用,并且管理大量的并行计算。RapidMind的运行步骤如下:

1:将数据类型转换成RapidMind的数据类型(整数和浮点)。
2:获得计算(当编码运行的时候,RapidMind可以获取编码中的操作,动态的汇聚到程序中)
3:流执行Stream Execution。(RapidMind的运行时间run-time管理着GPU的目标)

    RapidMind也有一些案例,说明了GPU+RapidMind的高效,性能可以达到CPU的数倍。说到案例,下面,我们就具体来研究几个GPU案例。
 

成功案例

    GPU计算有一些成功的案例。其中一个叫做Folding at Home。Folding at Home是一个研究性应用,志愿者可以下载,以帮助科学家来改进蛋白质问题的研究。2006年9月26日,ATI将Folding at Home装入GPU中。ATI声称,ATI X1900 显卡可以得到20倍到40倍于CPU的性能。ATI表示,以往3年工作量才能解决的问题,采用了ATI显卡之后,可以在一个月内完成。

    另一个成功案例,是马萨诸塞州通用医院。在医院里,X光通过称作数码Tomosynthesis的进程,生成实时影像。过去,医院采用35节点的集群来计算任务。而采用了NVIDIA G80 GPU,医院获得了100倍于CPU的性能。这意味着,同样的工作可以交给工作站来处理,而不再是体积臃肿的集群。其实,这样的例子还有很多,也足见GPU的高速发展。
 

针对集群的GPU

    到目前为止,我们只讨论了单一节点的GPU使用。GPU编码也可以用于连接CPU,前提是CPU运行的是并行MPI。GPU势必在未来起到更大的作用,例如大规模应用于集群。其实现在,GPU也已经可以以某些方式用于集群。

    GPU集群,或者GPU为主的集群,最近被用于多屏显示(Tiled displays)。Chromium就是一个例子,Chromium可以实现并行渲染。通过若干GPU计算节点,Chromium可以来驱动多个显示或者单一显示。

    斯坦福大学的Mike Houston,已经在GPU集群方面工作了一段时间。他所在的小组就正在尝试用并行GPU和HMM (Hidden Markov Models隐形马尔科夫模型)来进行蛋白质研究。HMM编码被重写,在GPU上运行,之后再被修正,数据库搜索被分成多个GPU集群节点。总体来讲,这并不是一个特别理想的集群,因为每个搜索都是独立的,因此全部搜索并非并行。但是每个节点的性能都很不错,大约达到了单一CPU的10~40倍,更重要的是,并行编码扩展得非常好。

    SUNY Stony Brook的虚拟化实验室,已经在GPU集群上努力了好几年。该工作室在GPU分布式图像和分布式计算领域有着较深的研究。2004年,虚拟化实验室发布了Lattice Boltzmann Method (LBM) GPU集群的研究报告,该报告是纽约时代广场的空气污染模拟状况。这个小组在研究的时候,采用了显卡到集群中的节点,来重写LBM编码。因为GPU不能直接访问网络界面,数据在传输时转换成CPU能识别的编码,而在节点处则被转换回GPU能够识别的编码。通过这种方法,程序员得到了4.6倍于CPU的速度提升。

    根据LBM编码的经验,虚拟化实验室最近也开发出了专门用于GPU集群的中间件ZippyGPU。ZippyGPU运行在GPU接口之上,负责压缩和管理API提供的函数和对象,并且简化代码。代码可以通过ZippyGPU访问网络和GPU。ZippyGPU主要用来支持虚拟化、图像合成、GPU计算。

    Acceleware是一家专门开发GPU软硬件的厂商。他们的产品Accelerator Board是插在PCI-e上,来提供工作站的GPU处理。他们也可以给工作站提供2~4个加速器板。性能有多大提升呢?举一个例子来说明:Acceleware公司以共轭斜量法来写方程,在其中一个32-bit的问题上,采用加速器板得到了3倍于CPU的性能。

总结

    虽然目前HPC采用GPU进行大量计算的案例还很少,但是我们从现有的案例中已经可以看到GPU的巨大潜力。虽然GPU用于HPC仍旧存在很多问题,但是随着技术的发展,我们对GPU的未来充满了信心。

0
相关文章