现在的位置: 首页 > 综合 > 正文

OpenCL和CUDA全解释

2018年04月03日 ⁄ 综合 ⁄ 共 10126字 ⁄ 字号 评论关闭
 Khronos组织最近规范了OpenCL 1.0, OpenCL实际上是针对异构系统进行并行编程的一个全新的API,简单来说OpenCL它可以利用GPU,然后进行一些并行计算这方面的工作,这是API应用程序的编程接口,图形里面也有很多API,比如OpenGL那是针对图形的,OpenCL是针对并行计算的API。OpenCL开发人员可以利用GPU和CPU的计算能力,把GPU和CPU异构的系统运用在很多并行计算的领域里面。Khronos是一个组织,有很多厂商组成,有非常多的成员,这个工作组同时也是OpenCL的一个协调机构,也就是Khronos这个工作组他来负责制定OpenCL的规格、架构等等各方面。业界最主要的和图形或者和计算相关的厂商都是Khronos的成员。

  OpenCL里面有很多的成员,这就导致了有更多可以利用OpenCL来开发的程序、软件以及各种各样的应用。这从一方面肯定了OpenCL强大的聚合实力,但一方面也预示着这将会形成一个旺盛的需求。实际上,OpenCL对于业界来说是非常重要也是非常好的一个标准,NVIDIA看准了这一标准,利用GPU的强大计算能力应用在图形以外各种各样的并行计算方面,NVIDIA一直在参与OpenCL的工作。NVIDIA副总裁Neil
Trevett,目前则是OpenCL工作组的主席,引导很多OpenCL的开发。这个组织里面当然还有很多其他开发公司。NVIDIA公司不少员工都在参与这项工作。

  OpenCL最早是Apple公司提出来的,由于OpenCL一开始NVIDIA就和Apple公司进行非常紧密的合作。所以目前OpenCL也完全是基于NVIDIA GPU的平台进行开发的。Apple十分重视OpenCL,不管是MacBook Pro、Mac OSX等新产品采用了NVIDIA的平台。目前OpenCL路线图目前还是属于Alpha版本,明年第一季度可能是Beta的版本,09年时OpenCL1.0可能正式推出,OpenCL最开始可能出现在Mac
OS上,以后逐渐的扩展到其他的操作系统,像Windows或者Linux。

  NVIDIA一直还是不断地对这个语言进行更深层次的开发,到目前为止已经是CUDA 2.0。开发人员的数量已经超过25000个,应用程序数量也已经超过100个,特别是很多的科学计算的领域等几乎涉及到各种各样的HPC高性能计算的领域都有CUDA的身影出现,甚至现在HPC进入排行榜前100的高性能计算机里面也有使用Tesla系统,Tesla系统就是一个GPU集群计算典范,现在支持Windows、Linux、Mac
OS,几乎最主流的操作系统NVIDIA都能支持。CUDA最主要的包含两个方面:一个是ISA指令集架构;第二硬件计算引擎;实际上是硬件和指令集,这两个方面是CUDA的架构。从这张图片可以看到,当GPU变身成CUDA运算时候,NVIDIA的GPU的架构就全是CUDA的架构,你可以把它看成是跟X86或者cell,他们都是架构,这个也是CUDA架构,但是是基于GPU的架构。这个和CPU的架构很类似,比如X86是包含一套指令集和执行X86各种各样的CPU,对于CUDA也是一样的,NVIDIA自有一套指令集ISA,还有各种各样执行指令集各种各样的硬件引擎。另外CUDA到目前为止,它包含了一个C语言的编译器,就是在CUDA上面的C语言,CUDA这个架构还可以支持其他的API,包括OpenCL或者DirectX,同时以后NVIDIA还有其他的语言,包括Fortran、Java、Python等各种各样的语言,可以说这种架构是原生的,专门为计算接口而建造的这样的一个架构,NVIDIA的硬件架构包括指令集都是非常适合于这种并行计算,这种异构计算而设计的一整套的架构。

  CUDA和OpenCL的关系是不冲突的,OpenCL是一个API,在第一个级别,CUDA这个架构是更高一个级别,但是在这个架构上不管是OpenCL还是DX11这样的API,还是像C语言、Fortran、DX11计算,NVIDIA都可以支持。作为程序开发员来讲,一般他只懂这些语言或者API,他可以选择我用什么样的语言来开发我的程序,不管他选择什么语言,他希望调用GPU的计算能,在这个架构上都可以用CUDA来编程,对于编程人员来讲这个很容易,他不需要对OpenCL的架构有非常深的了解,他就可以做到。这个方面上面实际上是一些开发工具,这个道理和CPU的编程实际上还是很类似的,比如你有X86的指令集,又有X86各种各样的CPU,然后你只需要对这个指令集编辑,X86架构上有各种各样的开发工具,当然也有C语言,Fortran语言有Python语言,或者是其他的像Java或者以前的Pascal语言,你用不同的语言进行开发,最后你的执行还是在X86的架构上执行。NVIDIA的CUDA也是一样,有CUDA这一套指令集,有这样的硬件,也就是说有不同的途径来进行开发,你可以用OpenCL或者DirectX这样的API来进行计算的开发,也可以用C语言或者Fortran或者Java开发,这个道理是一模一样的,可以做这方面的类比。OpenCL和C语言的一些异同点。对于编程人员来说他可以选择不同的东西来进行编程,就像之前说的可以选择OpenCL编程也可以选择CUDA上面的C语言来编程,或者API的语言来编程。API和C语言进行开发是有一些不同的,API是一个编程接口,它的核心是函数库和应用程序开发的一个硬件接口,对于API来编程的话,它有一个好处,那就是可以访问比较低层次的硬件,但是他也有一点,就是很多的东西特别是像内存的管理,这个是需要程序员自己来进行管理的。而C语言相对来说NVIDIA在利用CUDA
C语言来编程的时候,很多东西是由开发环境来进行管理的,比如内存他是用runtime进行管理的,runtime实际上就是运行时的一些支持程序来进行这方面的管理。不管OpenCL或者CUDA C语言来编程,最终它都是需要通过一个驱动程序来变成一个PTX的代码,PTX相当于CUDA的指令集来进行执行,然后交给图形处理其或者交给硬件来进行执行。这两个最终达到都是使用PTX或者在GPU上进行执行。基本上大家可以理解为
如果你想获得更多的对硬件上的控制权的话,你可以使用API来进行编程,比如我是一个科学家我对API不是太了解,你也可以用CUDA
C语言来编程
,这是两种不同编程的方式,他们有他们相同点和不同点。但是有一点OpenCL和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来编程,编完程序以后也可以在CPU的硬件上跑,这个东西不需要在CUDA支持GPU上跑。讲这个的目的是不同的编程模式可以选择不同的方法,就是用OpenCL还是用CUDA
C语言。

   OpenCL和OpenGL在很多方面都很类似,实际上他们也是一个共同的组织来进行管理的。对OpenGL图形开发比较熟悉的人他使用OpenCL计算这方面的开发,他们就会非常熟悉它里面所涉及的很多方面,这是OpenCL的一个非常明显的特点。如果你对图形编程很熟悉的话,使用DX11编程,可能比较容易,这是API的一个好处。但是对于大部分的科学家来说,可能对API,OpenCL这种东西可能完全不熟悉,他需要的是我就像在CPU上编程一样,对CPU的计算编程,他可以使用CUDA
C语言,在CUDA C语言里面把CPU看成专门做计算的协处理器来进行编程的。这是两个之间不同的模式。

总结:
  OpenCL不管对开发人员还是业界人员来说还是消费者来说都是一个非常好的API,一个应用程序的接口。它可以使得开发者很容易的开发出跨平台的GPU计算的程序,充分利用GPU强大的计算能力然后应用在各种各样计算的方面。
  对于NVIDIA来说,在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语言,刚才介绍有25000名这样的开发者,应用程序也有很多,而且这种应用程序每一刻都在不断地增加数量。CUDA C语言还会进一步的发展,就像刚才所说的还会有新的版本推出,而且会和像OpenCL和DX11这种计算API会共存,今后也是这样。除了C语言以外NVIDIA还会推出更多的其他CUDA的语言,包括Fortran,还会有Java等。
关于OpenCL与CUDA的一些问题:
问:
AMD是OpenCL里面的吗?
答:
对。OpenCL是包含很多家公司的,主要业界的公司都包含在里面,包括IBM、戴尔这些公司包括HP。OpenCL是一个非常开放的行业组织,所有的公司都在里面,他们和NVIDIA是没有冲突的,NVIDIA也是很积极地参与技术。
  Stream基本上还是基于一种传统CPU的一种方式,AMD当然他会说他会有CAL,CAL实际上是套指令集,可以用汇编语言的方式来开发软件,但是汇编方式开发软件的话,对搞计算的人来说不大现实,你要让他用汇编语言来说的话可能确实是一个折磨。还有一个Brook,这个是斯坦福大学开发的,它是类似于C的东西,他是把底层GPGPU的计算方式类似于C的这种语言,他不是C语言而是类C语言,语法和C语言比较类似,他内部做的还是使用顶点这样的数据。
  另外Stream的方式还有一个很大的问题,他主要是基于本地的板载内存,板载内存存入数据,然后换算完了再写到板载内存。这样对GPU非常强大的计算能力来说,带宽是一个非常大的障碍,你想想每秒种进行1P的数字计算的话,你需要多少的带宽?32位浮点的话这是4个字节,如果你1P的话,NVIDIA把他承加这部分也算上就相当于再乘以2,至少需要每秒2P的吞吐量然后才能够满足它,板载内存的话每秒需要几十P,这实际上是Stream的方式,从效率上是一个比较低的计算。而对于开发者来说也会碰到很多的问题,对于NVIDIA来说支持C,这是真正GPU上运行的C语言。C语言有一个很重要的特点,需要有存储体系,对于NVIDIA
GPU来说是有存储体系的,内部有share memory,然后大部分的数据,编译器会把大部分的数据尽可能的让它在share memory上进行计算,share memory带宽非常高,因为它在芯片内部,它的速度接近于寄存器的速度,他在share memory上跑的话,然后再把这个数据再输出,这样的话他真正地可以利用到绝大部分的计算机。实际上CUDA的效率,在应用软件上可以看出来,像传统的高性能计算领域的话,NVIDIA的峰值速度比如像G80是300多G浮点计算能力,效率是非常高的。这也是为什么这么多人在使用CUDA
C语言来进行开发,这是一个很重要的原因。

   实际上你说要使用Stream来开发的应用软件,我知道的只有一个是folding@home,ATI比NVIDIA进入早两年,但是NVIDIA进入以后使用CUDA的语言来写folding@home客户端的软件,性能立刻比它高好几倍,folding@home你可以看到一个很特别的——他原来一个版本是可以跑在它上一代的架构应该是3850或者3870的GPU上,但是如果它4850和4870出来以后,从原点上来说他的计算能力比3850、3870要高2.5倍,但是它的folding@home的性能反而下降了,原来他是200左右,就是3870,他是每天可以模拟200万秒的性能等级,4870出来以后每天只能模拟170万秒。这是为什么?这个软件不是使用Brook开发的,直接使用汇编的方式开发的,这样的话你需要对每一个新的GPU,你都要对他进行编程,每个架构都需要对它重新进行编程,然后才可以得到一个最好的效率。中间有很长时间4870的性能都比3870在folding@home上低,后来他确实重新编程了,过了好几个月,有些新的版本出来了,4870比3870高了。这就是说使用汇编方式的话会带来一个非常大的问题,你任何一个应用软件里面都需要重新优化、重新编程。
  汇编语言实际上就是机器码来进行编程,这个是属于体力比较好的人才能干的了,就是记忆也比较好的人才能干的了。高级语言相对来说确实要简单太多了,就像刚才我说的有些人甚至对编程都不是很熟悉的,他只要基本上知道源代码里面哪些代码是在做什么东西,然后他就可以使用CUDA,他不见得核心部分计算部分一定要自己编,就像刚才说的NVIDIA有很多现成的库,都是直接写好的函数,这个函数把原来的函数替代掉,就可以取得很好的性能。NVIDIA提供很多函数库,这些函数库有一些是NVIDIA公司开发的,像FFT、线性代数或者是快速傅里叶变换等,但是有一些库是第三方帮NVIDIA开发的。NVIDIA实际上形成一个非常好的环境,不断的有人针对CUDA来开发,不管是应用软件或者是中间件,这些中间件的话就包含各种各样的库。
对于CUDA来说,说老实话和Stream相比的话,几乎现在没什么可比性。确实对OpenCL、DirectX这样应用的话,我相信在CUDA的架构上运行这个程序也比在Stream上运行程序好的多。因为NVIDIA使用的架构实际上你开发的时候,NVIDIA就考虑到计算方面的应用。别的方案的话,他有可能计算仅仅是图形的一个副产品。NVIDIA在开发的时候图形和计算这两部分几乎作为同等重要的,两个都必须要满足的东西来做架构方面的设计。
问:
OpenCL它的特点一个是开放,OpenGL也很开放,但是它的更新实际上非常、非常的慢,OpenCL会有这种情况吗?
答:更新的话,这是由一个专门的组织Khronos,这个组织是有很多厂商来组成的,每个厂商派一些人然后进来在组织里面,然后每个公司互相协商,然后制定各种各样的标准,比如你推出一个新的版本要达到什么功能,价格是怎么样的?这些厂商来进行协商的,厂商不太一样,比如Microsoft我自己的东西,我说的算,这是完全不一样的。但是我相信OpenCL从目前来看的话,它还是挺快的,你看它现在的α版本明年一季度就进入β版本,明年终第一版就会推出。
问:
OpenGL和DirectX的关系一样,我现在看到CUDA这边更新的频率明显比OpenCL快很多,NVIDIA想把这个东西打造成一个GPU通用计算上的DirecX吗?
答: 我觉得应该是没有什么可比性的。刚刚强调DirectX是API,CUDA不是API,CUDA是一个硬件架构。刚才说的很多版本是CUDA C语言的版本,这是CUDA C语言版本的路线图,(PPT)C是语言,CUDA是一个硬件架构,GPU的架构。大家很容易会把C和CUDA融在一块儿,不是这样的。CUDA架构类似与X86的架构。
实际上CUDA的C语言和OpenCL在并行计算这块,它的一些观念都挺类似的,包括它计算的数据组织方式都很类似。我相信NVIDIA在OpenCL的规格、开发方面联系一直是非常紧密的,包括Apple也参与到其中。NVIDIA在这方面的很多经验,也会得到一些体现。这两个程序之间的移植也是很容易的,现在他使用CUDA C语言来写,OpenCL出来以后,如果他想移植OpenCL的程序,相对来说不用全部重头写。

问:
这个东西能否用在微软上?
答:
可以,像OpenGL也不是微软的,但是一样可以在微软上跑。
问:
现在一般都是OpenCL?
答:
这个是程序模型的原因,而且现在看起来在OpenCL在Vista下,目前看起来没有太大的问题。原来大家都一直以为在Vista下面OpenCL不会有ICD,实际上最后还是有ICD。这个东西的话现在OpenGL的软件,我经常跑各种各样的专业软件,很多在OpenGL下来以后都没有问题,非常典型的OpenGL的应用程序跑地都挺好的。对于OpenCL或者OpenGL在微软下,你可以看成是一个API,这个API你是可以安装的,比起微软自己原来带有的这个东西。这算是一种应用程序吧。
问:
OpenCL看似更趋向于底层开发的API,那相对于CUDA C来说,OpenCL开发的程序执行效率会不会比CUDA C效率更高一些?
答:
完全不存在这个问题。说老实话效率高不高,并不取决于你用的什么语言,什么样的API,更大程度上取决于你的代码,你代码的优化程度是怎样的?这个才是影响他代码的效率。
问:
在OpenCL出来之前,CUDA并行计算的优势已经很大了,现在为什么还非要出一个OpenCL通过中间的东西来调用,我感觉不是费一道事吗?
答:
OpenCL是一个跨平台的一种API,这个API就像OpenGL一样,它也是希望跨平台,就是跨软件和硬件的API,OpenCL也是一样也是跨软件和硬件平台的API,算是一个业界的标准,不管是哪一家的,原则上都可以支持OpenCL这个平台,支持API。OpenCL不是NVIDIA推出来的,OpenCL最开始是Apple提出来的,但是NVIDIA确实是在这个标准的制定当中,NVIDIA和Apple进行了很紧密的合作,然后NVIDIA提供了很多支持包括硬件方面的支持。
模式不一样适用的人群也不一样。适用的人群也不一样,我的理解是OpenCL和OpenGL他们在很多方面都非常的接近,如果习惯使用OpenGL他如果用OpenCL来开发的话会感觉到轻车熟路,就像是Computer shader也一样,如果你是多媒体这方面的应用,你又想使用图形又想使用GPU的来计算,你用Computer shader来做很容易。但是对CUDA C来说,它是用的人群是你能够使用C语言的人你都可以使用CUDA C来开发。使用人群完全是不一样的,我想可能也有一些人虽然他也会C语言,但是他还是希望用OpenCL来进行开发,用他跨平台的特性。另外或者因为其他的一些原因,包括他希望更多对硬件方面的控制,然后他应用软件里面他可能希望对内存进行完全的控制,这些用户的话他可能就会选用OpenCL来进行开发。这是两个不同的东西。我相信即使OpenCL出来以后,CUDA
C语言的使用者还是会越来越多的。

如果认为一种开发环境就可以取代其他的开发环境,这个是不现实的。我举个例子来说在X86的架构上,除了C语言以外还有Java、Fortran还有Pascal语言,这些不可能互相取代的,每种语言、每种API都有它使用的人群,都有喜欢用的人。不同的语言、不同的API都会满足不同人群的。我觉得现在不是太多,GPU计算和API语言不是太多,现在还比较少,NVIDIA还会不断地推出Java、Pascal或者C++也会支持。如果以前没有Fortran,那些老年人你要让他们学习C语言的话,他们可能用Fortran用了几十年,所以说让他开发的话他就比较痛苦,现在有了Fortran,他就可以直接用Fortran来写CUDA的程序,说不同开发的途径有不同的用户,这个是肯定的。
问:
Havok现在怎么样了?
答:
Havok目前为止基本上只能使用CPU做物理计算,而PhysX可以使用GPU、可以使用CPU也可以使用PPU来做物理方面的计算。当然这三种里面GPU的效率是最高的,PPU的话估计现在也没什么人买,GPU的效率是最高的,而且他真的是可以带来10倍的性能提升,这个性能提升在物理计算方面,CPU和GPU相比的话性能提升10倍,这是很常见的。而且PhysX它是可以作为一种最基本的平台,还有很多第三方的中间件在上面,基于PhysX。它实际上是利用PhysX的平台可以实现别的东西,比如类似于人工智能。NVIDIA曾经给大家提供过一个美式橄榄球的游戏视频,那个游戏真的是很酷,但是我不能放给大家看,那家公司要求NVIDIA只能提供视频给大家,不能把游戏给大家看。真的是很酷,非常大的场面,那个场面里面每个观众都是一个不同的人,有一个体育场9000人,每个观众都是一个实际的人,而且每个观众都是不太一样的。最主要他真正的把人的动作模拟的非常逼真,你撞击撞到什么位置,比如说你看到撞过来的你会下意识的做一些防守的动作。这些防守的动作人跑过来不同的方向,动作也不一样的。比如你跌倒,跌倒空中你可能会有下意识的支撑动作,这些都会有,以后游戏真的是会越来越逼真。NVIDIA所谓静态逼真和动态逼真就是这样。静态逼真像这个,Crysis已经做的很逼真了,但是真正动起来还是感觉比较僵硬,就是整个场景里面不管人物的动作或者其他的运动都是事先设置好的,就像放的录像一样,而不是真正时时运算出来的。如果你使用大量物理计算的话,真的可以获得很好的动态逼真度。如果要实时计算对硬件的要是就会很高,如果持有CPU加速的话它的动态架构和NVIDIA的动态架构就有区别,就会影响速度不一样。Havok用CPU来做物理计算,它计算能力只能那么高,你里面设置的物理效果相对来说就会很有限。而且CPU还有很重要的任务在人工智能或者场景管理的方面,所以说使用GPU来做物理方面的加速是非常有效的。另外还有一点新的180驱动支持更多的GPU
PhysX的配置,你可以使用2片的显卡,一片用来渲染,一片用来做物理加速,这是效率最高的一种方式。你用一片来做同时做渲染同时做物理计算,这也是可以的,和纯粹使用CPU做物理计算的话性能会高很多,但是并行计算和渲染都是需要GPU的计算资源,所以如果你用单独的一片显卡的话,用来做物理加速的话,性能又会得到一个很大的提升。大家最好可以测试一下这方面的效果。

问:
比如像EA的100多款游戏,它那个PhysX主要是用GPU运算还是CPU运算?
答:
只要是PhysX支持的游戏当然是GPU了。每一款游戏都可以采用不同的策略,我相信这些游戏开发商的话也会采用不同的策略来处理这些事情,当然他最好的效果肯定是使用GPU来做物理这方面的计算,然后游戏里面放大量的物理效果,这是最好的方式。当然也会有一些比较简化的模式,就是说你没有NVIDIA的显卡,然后给你提供一个比较简单,物理效果比较少的模式。你还可以运行,但是物理效果带来的各种各样的好处相对就比较少。这也是为什么跟大家强调的,NVIDIA现在叫GeForce
+ CUDA,里面有很多的新功能,PhysX是NVIDIA独有的,这是别人没有办法做到的。你要想作为一个玩家,你想享受更好的效果当然要在NVIDIA的显卡上运行,才会有更好的效果。这个市场是开放的,谁都可以去,但是看谁能够跑在前面。

问:
PhysX是跨平台的吗?PhysX主要是用于游戏吗?现在大部分的游戏基本上都是DirecX的。
答:
游戏机也可以支持。OpenGL和DirecX的API是独立的,现在OpenGL游戏确实越来越少,所以大部分的游戏都是DirecX的。
问:
PhysX不是跑在CPU上的?
答:
他是跑在GPU上。对于PhysX来说CPU也可以跑。

 

【上篇】
【下篇】

抱歉!评论已关闭.