谁主沉浮 OpenCL与CUDA架构深入解析
第1页:前言 |
最近,Khronos公布了OpenCL(Open Computing Language)的第一个测试版本,一经发布便在通用计算领域掀起来轩然大波!OpenCL是由苹果公司发起,业界众多著名厂商共同制作的面向异构系统通用目的并行编程的开放式、免费标准,也是一个统一的编程环境。便于软件开发人员为高性能计算服务器、桌面计算系统、手持设备编写高效轻便的代码,而且广泛适用于多核心处理器(CPU)、图形处理器(GPU)、Cell类型架构以及数字信号处理器(DSP)等其他并行处理器,在游戏、娱乐、科研、医疗等各种领域都有广阔的发展前景。
那么OpenCL与NVIDIA的CUDA架构是什么关系,是否是外界认为的竞争关系?目前众多的通用计算标准中,比如NVIDIA的CUDA、Khronos的OpenCL、AMD的Stream,CAL、Brook+、微软下一代的Computer shader等,他们之间有什么异同,看完这篇文章,相信你就会有一个大概的了#p#page_title#e#
#p#page_title#e#
第2页:OpenCL来了!
Khronos是一个开发组织,著名的OpenGL就是出自Khronos之手,Khronos有很多厂商组成,OpenCL工作组同时也是OpenCL的一个协调机构,来负责制定OpenCL的规格、架构等等各方面。业界最主要的和图形或者和计算相关的厂商都是Khronos的成员。
OpenCL实际上是针对异构系统进行并行编程的一个全新的API,OpenCL可以利用GPU进行一些并行计算的工作。我们知道,图形里面有很多API,比如OpenGL是针对图形的,而OpenCL则是针对并行计算的API。 OpenCL开发人员可以利用GPU和CPU的计算能力,把GPU和CPU异构的系统运用在很多并行计算的领域。
OpenCL对于业界来说是非常重要也是非常好的一个标准,这样业界有一个共同的标准可以利用GPU的强大计算能力,然后应用在图形以外各种各样的并行计算方面。nVIDIA公司的副总裁Neil Trevett是OpenCL工作组的主席,引导很多OpenCL的开发,NVIDIA公司很多员工都在参与这项工作。
OpenCL最早由Apple公司提出的,OpenCL发起NVIDIA就和Apple公司进行非常紧密的合作。OpenCL开发的过程中,技术平台均为NVIDIA的GPU,实际上OpenCL是基于NVIDIA GPU的平台进行开发的。另外OpenCL在大概两个多月以前进行了第一次演示,也是运行在NVIDIA的GPU上。
对于Apple公司来说是把GPU计算当成一种未来的趋势,他们非常重视OpenCL,在新一代的产品里面选择了最适合于OpenCL运行的平台。所以新一代苹果的笔记本电脑全都采用了NVIDIA的平台,不管是MacBook Pro还是MaBook。实际上这也是从另外一个方面证明NVIDIA的GPU对于OpenCL的支持。
#p#page_title#e#
第3页:OpenCL与CUDA并非敌对关系 |
很多人对什么是CUDA可能还有一些疑虑,并没有搞清楚CUDA到底是什么。实际上CUDA最主要的包含两个方面:一个是ISA指令集架构;第二硬件计算引擎;实际上是硬件和指令集。 也就是说我们可以把CUDA看做是与X86或者cell类似的架构,但是是基于是GPU,而不是传统的CPU。
这个其实很好理解,把它和传统的和CPU的架构比较下相信就更容易理解,传统X86是包含一套指令集和执行X86各种各样的CPU,对于CUDA也是一样,CUDA有一套指令集ISA,还有执行指令集各种各样的硬件引擎。CUDA到目前为止包含了一个C语言的编译器,当然CUDA架构还可以支持其他的API,包括OpenCL或者DirectX,同时CUDA还会有其他的语言,包括Fortran、Java、Python等各种各样的语言,可以说CUDA架构是原生的,专门为计算接口而建造的这样的一个架构,这种硬件架构包括指令集都是非常适合于这种并行计算,为异构计算而设计的一整套的架构。
OpenCL与CUDA的关系
上图很好的解释CUDA和OpenCL的关系,他们并不是冲突关系,而是包容关系。OpenCL是一个API,在第一个级别,CUDA架构是更高一个级别,在这个架构上不管是OpenCL还是DX11这样的API,还是像C语言、Fortran、DX11计算,都可以支持。作为程序开发员来讲,一般他们只懂这些语言或者API,可以采用多种语言开发自己的程序,不管他选择什么语言,只要是希望调用GPU的计算能,在这个架构上都可以用CUDA来编程。
CUDA编程的道理和CPU的编程很类似,比如有了X86的指令集,又有X86各种各样的CPU,那么我们只需要对这个指令集编程即可。X86架构上有各种各样的开发工具,当然也有C语言,Fortran语言,Python语言,Java或者以前的Pascal语言,不论你使用什么语言进行开发,最后还是在X86的架构上执行。CUDA也是一样,有了CUDA的指令集,有了支持CUDA的硬件,我们就可以采用不同的途径来进行开发,比如可以采用OpenCL或者DirectX这样的API,也可以用C语言或者Fortran或者Java开发,最终都可以在CUDA架构上运行。
#p#page_title#e#
第4页:OpenCL与CUDA C语言的异同 |
前文已经说过,CUDA架构与OpenCL是包容关系,我们把他们放在同一级别进行讨论本来就是错误的,与OpenCL在同一级别不是CUDA架构,而是CUDA的C语言包,也就是我们常说的CUDA版本,比如,CUDA 1.0、CUDA 2.0等等,下面来介绍一下OpenCL和CUDA C语言的一些异同。
对于编程人员来说可以选择不同的开发环境来进行编程,例如我们可以选择OpenCL编程也可以选择CUDA上面的C语言来编程,或者API的语言来编程。API和C语言进行开发是有一些不同的,API是一个编程接口,它的核心是函数库和应用程序开发的一个硬件接口,对于API来编程的话,好处在于可以访问比较低层次的硬件,单弊端也是显而易见的,那就是很多程序特别是像内存的管理,需要程序员自己来进行管理。而我们在利用CUDA C语言来编程的时候,底层的硬件管理是由CUDA开发包来进行管理,比如内存是用runtime进行管理(runtime实际上就是运行时的一些支持程序来进行底层硬件的管理),而不需要开发者考虑底层的硬件效率。不管OpenCL或者CUDA C语言来编程,最终都是需要通过一个驱动程序来变成一个PTX的代码,PTX相当于CUDA的指令集来进行执行,然后交给图形处理其或者交给CPU来进行执行。
也就是说,如果开发人员想获得更多的对硬件上的控制权的话,可以使用API来进行编程,而如果类似科学家如果对API不是太了解,那么就可以用CUDA C语言来编程,这是两种不同编程的方式,他们有他们相同点和不同点。OpenCL和CUDA C语言进行开发的时候,在并行计算上的概念很相似,在程序上是也有很大的相似度,所以程序之间的相互移植相对来说也比较容易。
当然我们也许会有疑问,那就是OpenCL看似更趋向于底层开发的API,那相对于CUDA C来说,OpenCL开发的程序执行效率会不会比CUDA C效率更高一些?实际上这个问题是不用担心的,执行效率高不高,并不取决于采用的什么语言,什么样的API,更大程度上取决于的代码的优化程度!
#p#page_title#e#
第5页:不同编程模式解读 |
下面我们来深入解读一下CUDA与C语言编程模式的异同。对C语言进行编程的人员都知道,C语言使用驱动程序就是API,实际上是一种抽象,这个抽象主要是指和硬件相关的抽象。实际上CUDA C语言是一种C语言的扩展,这扩展的一部分主要是进行并行运算编程的方面,这些是通过C的扩展来获得的。基本上认为CUDA的程序也是一种标准的C语言的程序,然后使用一些关键字然后来对并行这方面计算,最后做一些区分。C语言最终编译会成为PTX的代码,然后在GPU上执行。OpenCL是一个API,就是应用程序的编程接口,OpenCL和OpenGL很像,这种API可以调用API最底层的数据,通过程序开发调用各种各样的函数,实现各种各样的功能。对于API来说一般它对硬件设备有比较完整的访问权,以访问硬件的设备,可以对内存进行管理,这是由开发人员通过编程来做的这些事情。最后OpenCL通过编译、通过驱动程序可以生成PTX代码在GPU上进行执行。
编程人员要利用GPU的计算能力开发你的应用的时候,有两种模式:如果你需要对硬件有更多的控制,可以通过OpenCL来编你的API和你的程序,那么它可以在CPU上运行;如果不需要底层的硬件管理,同时对硬件有控制权,而且又不太懂API这些程序,只要用C语言就可以编程了,或者CUDA C语言来编程,编完程序以后也可以在CPU的硬件上运行。
OpenCL和OpenGL在很多方面都很类似,他们也是一个共同的组织Khronos来进行管理的。对OpenGL图形开发比较熟悉的人使用OpenCL计算这方面的开发,他们就会非常熟悉它里面所涉及的很多方面,这是OpenCL的一个非常明显的特点。如果你对图形编程很熟悉的话,就像是Computer Shader,如果是多媒体等方面的应用,又想使用图形又想使用GPU的来计算,用Computer Shader的DX11编程,可能比较容易。但是对于大部分的科学家来说,可能对API,OpenCL可能完全不熟悉,他需要的就像在CPU上编程一样,对CPU的计算编程,可以使用CUDA C语言,在CUDA C语言里面我们把CPU看成专门做计算的协处理器来进行编程,这是两个之间不同的模式。
如果认为一种开发环境就可以取代其他的开发环境,这个是不现实的。举个例子,在X86的架构上,除了C语言以外还有Java、Fortran还有Pascal语言,这些不可能互相取代的,每种语言、每种API都有它使用的人群。不同的语言、不同的API都会满足不同人群的。GPU计算和API语言不是太多,目前还比较少,NVIDIA还会不断地推出Java、Pascal或者C++也会支持。如果以前没有Fortran,那些“老古董”程序员要让他们学习C语言的话基本不可行,他们可能用Fortran用了几十年,让他们使用C语言开发的话他就比较痛苦,所以OpenCL与CUDA C语言并不存在谁将取代谁的问题。
#p#page_title#e#
第6页:CUDA与ATI Stream异同 |
我们知道,ATI方面也有自己的通用计算编程接口,叫做Stream。那么他与CUDA架构又有什么不同呢?
Stream基本上还是基于一种传统CPU的一种方式,Stream主要包括CAL与Brook+。CAL是一套指令集,可以用汇编语言的方式来开发软件,然而我们汇编方式开发软件的话,对搞计算的人来说不大现实,让他们用汇编语言来说的话可能确实是一个折磨。Brook+是斯坦福大学开发的,它是类似于C语言的东西,是把底层GPGPU的计算方式类似于C的这种语言,这里要说明的是Brook+不是C语言而是类C语言,语法和C语言比较类似,但内部做的还是使用顶点这样的数据。
Stream视频编码
另外Stream的方式还有一个很大的问题,那就是主要是基于本地的板载内存存入数据,换算完成再写到板载内存。这样对GPU非常强大的计算能力来说,带宽是一个非常大的障碍。例如每秒种进行1P的数字计算的话,需要多少的带宽?32位浮点4个字节,如果是1P的话,我们把乘加这部分也计算在内就相当于再乘以2,至少需要每秒2P的吞吐量然后才能够满足,板载内存每秒需要几十P。可见Stream的方式从效率上是一个比较低的计算,而对于开发者来说也会碰到很多的问题。
对于CUDA来说我们支持的C语言,是真正GPU上运行的C语言。C语言有一个很重要的特点,需要有存储体系,而NVIDIA GPU在设计之初就考虑到了这点,内部有拥有share memory,编译器会把大部分的数据尽可能的在share memory上进行计算。share memory带宽非常高,因为它在芯片内部,速度接近于寄存器。数据在share memory上运行,然后再把这个数据再输出,这样的话真正地可以利用到绝大部分的GPU性能。
#p#page_title#e#
第7页:汇编语言的弊端 |
基于Stream来开发的应用软件,我们知道的只有一个是folding@home,ATI比NVIDIA进入早两年,但是NVIDIA进入以后使用CUDA的语言来写folding@home客户端的软件,性能比ATI的GPU要高好几倍。folding@home的一个版本可以运行在在上一代的架HD3850或者HD3870的GPU上,但是HD4850和HD4870发布后,从浮点性能上来说计算能力比HD3850、HD3870要高2.5倍,但是folding@home的性能反而下降了?原来HD3870是200ns/day左右,每天可以模拟200万秒的性能等级,但是HD4870发布后每天只能模拟170ns/day,这又是为什么?其原因是软件不是使用Brook+开发的,而直接使用汇编的方式,这就需要对每一个新的GPU进行编程,每个架构都需要对它重新进行编程,然后才可以得到一个最好的效率,这就是说使用汇编方式的话会带来一个非常大的问题,任何一个应用软件里面都需要重新优化、重新编程。
汇编语言实际上就是机械码来进行编程,属于体力比较好、记忆也比较好的人才能胜任的工作。高级语言相对来说确实要简单太多了,例如有些人甚至对编程都不是很熟悉,他只要基本上知道源代码里面哪些代码是在做什么东西,然后他就可以使用CUDA,核心部分计算部分一定要自己编写,因为CUDA有很多现成的库,都是直接写好的函数,这个函数把原来的函数替代掉,就可以取得很好的性能。NVIDIA提供很多函数库,这些函数库有一些是NVIDIA公司开发的,像FFT、线性代数或者是快速傅里叶变换等,但是有一些库是第三方帮NVIDIA开发的。CUDA实际上形成一个非常好的环境,不断的有人针对CUDA来开发,不管是应用软件或者是中间件,这些中间件的话就包含各种各样的库。
因此对于CUDA来说,与Stream相比几乎现在没什么可比性。对OpenCL、DirectX这样应用在CUDA的架构上运行程序也比在Stream上运行程序好的多。因为NVIDIA在使用的CUDA架构实际上字开发的时候,就考虑到通用计算方面的应用。而ATI方面,可能通用计算仅仅是图形的一个副产品。
#p#page_title#e#
第8页:OpenCL与CUDA C语言路线图 |
目前OpenCL路线图目前还是属于ALPHA版本。明年第一季度可能是Beta的版本,09年OpenCL1.0可能会正式推出,OpenCL最早会出现在Mac OS上,以后逐渐的扩展到其他的操作系统,像Windows或者Linux。
OpenCL路线图
下面来介绍一下CUDA C语言的情况,NVIDIA一直还是不断地对这个语言进行更深层次的开发,也不断的有新版本的出现,到目前为止已经是CUDA 2.0。CUDA C语言研发已经超过5年时间,NVIDIA从03年左右就开始开发C语言。到目前为止,开发人员的数量已经是超过25000个,而且现在应用程序已经超过100个,特别是很多的科学计算的领域,几乎涉及到各种各样的HPC高性能计算的领域都有CUDA的身影出现,甚至现在HPC进入排行榜前100的高性能计算机里面也有使用NVIDIA的Tesla系统,GPU集群就是配置成高性能计算机的集群数量已经达到了30个,我国大陆也有采用。
CUDA C语言是一个跨操作系统的开发工具,现在支持Windows、Linux、Mac OS,几乎最主流的操作系统都支持,SUN公司的Solaris系统也会支持。一些数学软件像Matlab、Mathematica、LabView都有CUDA的插件,可以使用C语言的插件让他更容易的利用CUDA。
上面是C语言的路线图,目前的版本是CUDA 2.0,到今年年底CUDA 2.1会与我们见面,到明年会有2.2、2.3版本,到明年年底会到CUDA 3.0版本。随着CUDA版本的升级,它的功能也在不断地升级,比如最早的CUDA只能支持单精度的浮点计算,现在可以支持双精度,可以支持各种各样的库,各种各样的功能也是越来越多。
#p#page_title#e#
第9页:并行计算时代已经到来…… |
OpenCL的面世,不管对开发人员还是业界人员来说还是消费者来说都是一个非常好的API,它可以使得开发者很容易的开发出跨平台的GPU计算的程序,充分利用GPU强大的计算能力然后应用在各种各样计算的方面。 除了CUDA的架构上除了C语言以外,现在新增加了OpenCL或者DX11这样的API,对于开发人员来说也提供了一种更多的GPU计算的开发环境的一种选择。如果对API很熟悉的程序员,肯定会很高兴的看到OpenCL或者新的API的加入,对于这些人来说他们很容易利用这种计算的API然后开发各种各样GPU计算的程序。
NVIDIA也会继续对C语言包括其他语言的支持,实对NVIDIA CUDA C语言来说目前还是唯一的针对GPU的runtime C的语言环境(runtime C的语言环境是指GPU直接执行这个C语言)。CUDA C语言还会进一步的发展,不断会有新的版本推出。CUDA C语言会和OpenCL和DX11这种计算API会共存。
除了C语言以外NVIDIA还会推出更多的其他CUDA的语言,包括Fortran,还会有Java等。不管C语言还是Fortran,与OpenCL、Computer shader这种API是一种长期共存的关系。 GPU通用计算时代已经到来了,你已经准备好了吗……