多謝大家關(guān)注 轉(zhuǎn)載本文請(qǐng)注明:http://blog.csdn.net/leonwei/article/details/8880012
本文將作為我《從零開(kāi)始做OpenCL開(kāi)發(fā)》系列文章的第一篇,。
1 異構(gòu)計(jì)算、GPGPU與OpenCL OpenCL是當(dāng)前一個(gè)通用的由很多公司和組織共同發(fā)起的多CPU\GPU\其他芯片 異構(gòu)計(jì)算(heterogeneous)的標(biāo)準(zhǔn),,它是跨平臺(tái)的,。旨在充分利用GPU強(qiáng)大的并行計(jì)算能力以及與CPU的協(xié)同工作,更高效的利用硬件高效的完成大規(guī)模的(尤其是并行度高的)計(jì)算,。在過(guò)去利用GPU對(duì)圖像渲染進(jìn)行加速的技術(shù)非常成熟,,但是我們知道GPU的芯片結(jié)構(gòu)擅長(zhǎng)大規(guī)模的并行計(jì)算(PC級(jí)的GPU可能就是CPU的上萬(wàn)倍),CPU則擅長(zhǎng)邏輯控制,,因此不只局限與圖像渲染,,人們希望將這種計(jì)算能力擴(kuò)展到更多領(lǐng)域,所以這也被稱為GPGPU(即通用處計(jì)算處理的GPU),。 簡(jiǎn)單的說(shuō),,我們的CPU并不適合計(jì)算,它是多指令單數(shù)據(jù)流(MISD)的體系結(jié)構(gòu),,更加擅長(zhǎng)的是做邏輯控制,,而數(shù)據(jù)處理基本是單流水線的,所以我們的代碼for(i=0;...;i++)這種在CPU上要重復(fù)迭代的跑很多遍,,但是你的顯卡GPU則不是這樣,,GPU是典型的單指令多數(shù)據(jù)(SIMD)的體系結(jié)構(gòu),它不擅長(zhǎng)邏輯控制,,但是確實(shí)天生的向量計(jì)算機(jī)器,,對(duì)于for(i=0;...;i++)這樣的代碼有時(shí)只需要跑一遍,所以圖形世界中那么多的頂點(diǎn),、片段才能快速的并行在顯卡中渲染處理
GPU的晶體管可以到幾十億個(gè),,而CPU通常只有幾個(gè)億,, 如上圖是NVidia Femi100的結(jié)構(gòu),它有著大量的并行計(jì)算單元,。 所以人們就想如何將更多的計(jì)算代碼搬到GPU上,,讓他不知做rendering,而CPU只負(fù)責(zé)邏輯控制,,這種一個(gè)CPU(控制單元)+幾個(gè)GPU(有時(shí)可能再加幾個(gè)CPU)(計(jì)算單元)的架構(gòu)就是所謂的異構(gòu)編程(heterogeneous),,在這里面的GPU就是GPGPU。異構(gòu)編程的前景和效率是非常振奮人心的,,在很多領(lǐng)域,,尤其是高并行度的計(jì)算中,效率提升的數(shù)量級(jí)不是幾倍,,而是百倍千倍,。 其實(shí)NVIDIA在很早就退出了利用其顯卡的GPGPU計(jì)算 CUDA架構(gòu),當(dāng)時(shí)的影響是很大的,,將很多計(jì)算工作(科學(xué)計(jì)算,、圖像渲染、游戲)的問(wèn)題提高了幾個(gè)數(shù)量級(jí)的效率,,記得那時(shí)NVIDIA來(lái)浙大介紹CUDA,,演示了實(shí)時(shí)的ray tracing、大量剛體的互相碰撞等例子,,還是激動(dòng)了一下的,,CUDA現(xiàn)在好像已經(jīng)發(fā)展到了5.0,而且是NVDIA主力推的通用計(jì)算架構(gòu),,但是CUDA最大的局限就是它只能使用N家自己的顯卡,,對(duì)于廣大的A卡用戶鞭長(zhǎng)莫及。OpenCL則在之后應(yīng)運(yùn)而生,,它由極大主流芯片商,、操作系統(tǒng)、軟件開(kāi)發(fā)者,、學(xué)術(shù)機(jī)構(gòu),、中間件提供者等公司聯(lián)合發(fā)起,它最初由Apple提出發(fā)起標(biāo)準(zhǔn),,隨后Khronos Group成立工作組,,協(xié)調(diào)這些公司共同維護(hù)這套通用的計(jì)算語(yǔ)言。Khronos Group聽(tīng)起來(lái)比較熟悉吧,,圖像繪制領(lǐng)域著名的軟硬件接口API規(guī)范著名的OpenGL也是這個(gè)組織維護(hù)的,,其實(shí)他們還維護(hù)了很多多媒體領(lǐng)域的規(guī)范,可能也是類似于Open***起名的(所以剛聽(tīng)到OpenCL的時(shí)候就在想它與OpenGl有啥關(guān)系),OpenCl沒(méi)有一個(gè)特定的SDK,,Khronos Group只是指定標(biāo)準(zhǔn)(你可以理解為他們定義頭文件),,而具體的implementation則是由不同參與公司來(lái)做,這樣你會(huì)發(fā)現(xiàn)NVDIA將OpenCL做了實(shí)現(xiàn)后即成到它的CUDA SDK中,,而AMD則將其實(shí)現(xiàn)后放在所謂是AMD APP (Accelerated Paral Processing)SDK中,而Intel也做了實(shí)現(xiàn),,所以目前的主流CPU和GPU都支持OpenCL架構(gòu),雖然不同公司做了不同的SDK,,但是他們都遵照同樣的OpenCL規(guī)范,,也就是說(shuō)原則上如果你用標(biāo)準(zhǔn)OpenCl頭中定義的那些接口的話,使用NVIDIA的SDK編的程序可以跑在A家的顯卡上的,。但是不同的SDK會(huì)有針對(duì)他們芯片的特定擴(kuò)展,,這點(diǎn)類似于標(biāo)磚OpenGL庫(kù)和GL庫(kù)擴(kuò)展的關(guān)系。 OpenGL的出現(xiàn)使得AMD在GPGPU領(lǐng)域終于迎頭趕上的NVIDIA,,但是NVIDIA雖為OpenCL的一員,,但是他們似乎更加看重自己的獨(dú)門武器CUDA,所以N家對(duì)OpenCL實(shí)現(xiàn)的擴(kuò)展也要比AMD少,,AMD由于同時(shí)做CPU和GPU,,還有他們的APU,似乎對(duì)OpenCL更來(lái)勁一些,。
2.關(guān)于在GPU上寫代碼的那些事兒 OpenCL也是通過(guò)在GPU上寫代碼來(lái)加速,,只不過(guò)他把CPU、GPU,、其他什么芯片給統(tǒng)一封裝了起來(lái),,更高了一層,對(duì)開(kāi)發(fā)者也更友好,。說(shuō)到這里突然很想贅述一些在GPU上寫代碼的那些歷史,。。 其實(shí)最開(kāi)始顯卡是不存在的,,最早的圖形處理是放在CPU上,,后來(lái)發(fā)現(xiàn)可以再主板上放一個(gè)單獨(dú)的芯片來(lái)加速圖形繪制,那時(shí)還叫圖像處理單元,,直到NVIDIA把這東西做強(qiáng)做大,,并且第一給它改了個(gè)NB的稱呼,叫做GPU,,也叫圖像處理器,,后來(lái)GPU就以比CPU高幾倍的速度增長(zhǎng)性能。 開(kāi)始的時(shí)候GPU不能編程,,也叫固定管線的,,就是把數(shù)據(jù)按照固定的通路走完 和CPU同樣作為計(jì)算處理器,順理成章就出來(lái)了可編程的GPU,但是那時(shí)候想在GPU上編程可不是容易的事,,你只能使用GPU匯編來(lái)寫GPU程序,,GPU匯編?聽(tīng)起來(lái)就是很高級(jí)的玩意兒,,所以那時(shí)使用GPU繪制很多特殊效果的技能只掌握在少數(shù)圖形工程師身上,,這種方式叫可編程管線。 很快這種桎桍被打破,,GPU上的高級(jí)編程語(yǔ)言誕生,,在當(dāng)時(shí)更先進(jìn)的一些顯卡上(記憶中應(yīng)該是3代顯卡開(kāi)始吧),像C一樣的高級(jí)語(yǔ)言可以使程序員更加容易的往GPU寫代碼,,這些語(yǔ)言代表有nvidia和微軟一起創(chuàng)作的CG,,微軟的HLSL,openGl的GLSL等等,,現(xiàn)在它們也通常被稱為高級(jí)著色語(yǔ)言(Shading Language),,這些shader目前已經(jīng)被廣泛應(yīng)用于我們的各種游戲中。 在使用shading language的過(guò)程中,,一些科研人員發(fā)現(xiàn)很多非圖形計(jì)算的問(wèn)題(如數(shù)學(xué),、物理領(lǐng)域的并行計(jì)算)可以偽裝成圖形問(wèn)題利用Shading Language實(shí)現(xiàn)在GPU上計(jì)算,而這結(jié)果是在CPU上跑速度的N倍,,人們又有了新的想法,,想著利用GPU這種性能去解決所有大量并行計(jì)算的問(wèn)題(不只圖形領(lǐng)域),這也叫做通用處理的GPU(GPGPU),,很多人嘗試這樣做了,,一段時(shí)間很多論文在寫怎樣怎樣利用GPU算了哪個(gè)東東。,。,。但是這種工作都是偽裝成圖形處理的形式做的,還沒(méi)有一種天然的語(yǔ)言來(lái)讓我們?cè)贕PU上做通用計(jì)算,。這時(shí)又是NVIDIA帶來(lái)了革新,,09年前后推出的GUDA架構(gòu),可以讓開(kāi)發(fā)者在他們的顯卡上用高級(jí)語(yǔ)言編寫通用計(jì)算程序,,一時(shí)CUDA熱了起來(lái),,直到現(xiàn)在N卡都印著大大的CUDA logo,不過(guò)它的局限就是硬件的限制,。 OpenCL則突破了硬件的壁壘,,試圖在所有支持的硬件上搭建起通用計(jì)算的協(xié)同平臺(tái),不管你是cpu還是gpu通通一視同仁,,都能進(jìn)行計(jì)算,,可以說(shuō)OpenCL的意義在于模糊了主板上那兩種重要處理器的界限,,并使在GPU上跑代碼變得更容易。
3 OpenCL架構(gòu) 3.1 硬件層: 上面說(shuō)的都是關(guān)于通用計(jì)算以及OpenCL是什么,,下面就提綱挈領(lǐng)的把OpenCL的架構(gòu)總結(jié)一下: 以下是OpenCL硬件層的抽象
它是一個(gè)Host(控制處理單元,,通常由一個(gè)CPU擔(dān)任)和一堆Computer Device(計(jì)算處理單元,通常由一些GPU,、CPU其他支持的芯片擔(dān)任),,其中Compute Device切分成很多Processing Element(這是獨(dú)立參與單數(shù)據(jù)計(jì)算的最小單元,這個(gè)不同硬件實(shí)現(xiàn)都不一樣,,如GPU可能就是其中一個(gè)Processor,,而CPU可能是一個(gè)Core,我猜的,。,。因?yàn)檫@個(gè)實(shí)現(xiàn)對(duì)開(kāi)發(fā)者是隱藏的),其中很多個(gè)Processing Element可以組成組為一個(gè)Computer Unit,,一個(gè)Unit內(nèi)的element之間可以方便的共享memory,,也只有一個(gè)Unit內(nèi)的element可以實(shí)現(xiàn)同步等操作,。 3.2 內(nèi)存架構(gòu) 其中Host有自己的內(nèi)存,,而在compute Device上則比較復(fù)雜,首先有個(gè)常量?jī)?nèi)存,,是所有人能用的,,通常也是訪問(wèn)最快的但是最稀少的,然后每個(gè)element有自己的memory,,這是private的,,一個(gè)組內(nèi)的element有他們共用的一個(gè)local memery。仔細(xì)分析,,這是一個(gè)高效優(yōu)雅的內(nèi)存組織方式,。數(shù)據(jù)可以沿著Host-》gloabal-》local-》private的通道流動(dòng)(這其中可能跨越了很多個(gè)硬件)。 3.3軟件層面的組成 這些在SDK中都有對(duì)應(yīng)的數(shù)據(jù)類型 setup相關(guān): Device:對(duì)應(yīng)一個(gè)硬件(標(biāo)準(zhǔn)中特別說(shuō)明多core的CPU是一個(gè)整個(gè)Device)
Context:環(huán)境上下文,,一個(gè)Context包含幾個(gè)device(單個(gè)Cpu或GPU),,一個(gè)Context就是這些device的一個(gè)聯(lián)系紐帶,只有在一個(gè)Context上的那些Device才能彼此交流工作,,你的機(jī)器上可以同時(shí)存在很多Context,。你可以用一個(gè)CPu創(chuàng)建context,也可以用一個(gè)CPU和一個(gè)GPU創(chuàng)建一個(gè),。
Command queue:這是個(gè)給每個(gè)Device提交的指令序列
內(nèi)存相關(guān): Buffers:這個(gè)好理解,,一塊內(nèi)存 Images:畢竟并行計(jì)算大多數(shù)的應(yīng)用前景在圖形圖像上,所以原生帶有幾個(gè)類型,,表示各種維度的圖像,。
gpu代碼執(zhí)行相關(guān): Program:這是所有代碼的集合,可能包含Kernel是和其他庫(kù),OpenCl是一個(gè)動(dòng)態(tài)編譯的語(yǔ)言,,代碼編譯后生成一個(gè)中間文件(可實(shí)現(xiàn)為虛擬機(jī)代碼或者匯編代碼,,看不同實(shí)現(xiàn)),在使用時(shí)連接進(jìn)入程序讀入處理器,。 Kernel:這是在element跑的核函數(shù)及其參數(shù)組和,,如果把計(jì)算設(shè)備看做好多人同時(shí)為你做一個(gè)事情,那么Kernel就是他們每個(gè)人做的那個(gè)事情,,這個(gè)事情每個(gè)人都是同樣的做,,但是參數(shù)可能是不同的,這就是所謂的單指令多數(shù)據(jù)體系,。 WorkI tem:這就是代表硬件上的一個(gè)Processing Element,,最基本的計(jì)算單元。
同步相關(guān): Events:在這樣一個(gè)分布式計(jì)算的環(huán)境中,,不同單元之間的同步是一個(gè)大問(wèn)題,,event是用來(lái)同步的
他們的關(guān)系如下圖
上面就是OpenCL的入門介紹,其實(shí)說(shuō)實(shí)話在10年左右就跟蹤過(guò)GPGPU相關(guān)的東西,,那時(shí)很多相關(guān)技術(shù)還存在于實(shí)驗(yàn)室,,后來(lái)的CUDA出現(xiàn)后,也激動(dòng)過(guò),,學(xué)習(xí)過(guò)一陣,,不過(guò)CUDA過(guò)度依賴于特定硬件,產(chǎn)業(yè)應(yīng)用前景并不好,,只能做做工程試驗(yàn),,你總不能讓用戶裝個(gè)游戲的同時(shí),讓他順便換個(gè)高配的N卡吧,。所以一度也對(duì)這個(gè)領(lǐng)域不太感興趣,,最近看到OpenCL的出現(xiàn),發(fā)現(xiàn)可能這個(gè)架構(gòu)還是有很好的應(yīng)用前景的,,也是眾多廠商目前合力力推的一個(gè)東西,。想想一下一個(gè)迭代10000次的for循環(huán)一遍過(guò),還是很激動(dòng)的一件事,。 在游戲領(lǐng)域,,OpenCL已經(jīng)有了很多成功的實(shí)踐,好像EA的F1就已經(jīng)應(yīng)用了OpenCL,,還有一些做海洋的lib應(yīng)用OpenCL(海面水波的FFT運(yùn)算在過(guò)去是非常慢的),,另外還有的庫(kù)干脆利用OpenCL去直接修改現(xiàn)有的C代碼,加速for循環(huán)等,,甚至還有OpenCl版本的C++ STL,,叫thrust,,所以我覺(jué)得OpenCL可能會(huì)真正的給我們帶來(lái)些什么~
以下是一些關(guān)于OpenCL比較重要的資源: http://www./opencl/ 組織的主頁(yè) https://developer./opencl N家的主頁(yè) http://developer./resources/heterogeneous-computing/opencl-zone/ A家的主頁(yè) http://www./registry/cl/sdk/1.2/docs/man/xhtml/ 標(biāo)準(zhǔn)的reference http://developer./wordpress/media/2012/10/opencl-1.2.pdf 必看 最新的1.2版本標(biāo)準(zhǔn) http://www./assets/uploads/developers/library/overview/opencl-overview.pdf 必看,入門的review http://www./opencl-1/opencl-jiao-xue-yi 一個(gè)教學(xué)網(wǎng)站 |
|
來(lái)自: 閱讀擴(kuò)展視野 > 《待分類》