1. 簡(jiǎn)介
OpenCL(Open Computing Language)痒钝,即開放運(yùn)算語(yǔ)言痴昧,是一個(gè)統(tǒng)一的開放式的開發(fā)平臺(tái)帆卓。OpenCL是首個(gè)提出的并行開發(fā)的開放式的巨朦、兼容的米丘、免費(fèi)的標(biāo)準(zhǔn),它的目的是為異構(gòu)系統(tǒng)通用提供統(tǒng)一開發(fā)平臺(tái)糊啡。OpenCL最初是由蘋果公司設(shè)想和開發(fā)拄查,并在與AMD,IBM棚蓄,英特爾和NVIDIA技術(shù)團(tuán)隊(duì)的合作之下初步完善堕扶。隨后,蘋果將這一草案提交至Khronos Group梭依。
2. 框架組成
OpenCL的框架組成可以劃分為三個(gè)部分稍算,分別為OpenCL平臺(tái)API、OpenCL運(yùn)行時(shí)API役拴,以及OpenCL內(nèi)核編程語(yǔ)言糊探。
2.1 平臺(tái)API
平臺(tái)(Platform)這個(gè)詞在OpenCL中擁有非常特定的含義,它表示的是宿主機(jī)河闰、OpenCL設(shè)備和OpenCL框架的組合科平。多個(gè)OpenCL平臺(tái)可以共存于一臺(tái)異構(gòu)計(jì)算機(jī)。舉個(gè)例子姜性,CPU開發(fā)人員和GPU開發(fā)人員可以在同一個(gè)系統(tǒng)上分別定義自己的OpenCL框架瞪慧。這時(shí)就需要一種方法來(lái)查詢系統(tǒng)中可用的OpenCL 框架,哪些OpenCL設(shè)備是可用的部念,以及這些OpenCL設(shè)備的特性弃酌。相當(dāng)于CUDA的主機(jī)和設(shè)備之間的關(guān)系。
此外儡炼,為了形成一個(gè)給定的OpenCL應(yīng)用平臺(tái)妓湘,還需要對(duì)這些框架和設(shè)備所屬的子集進(jìn)行控制。這些功能都是由OpenCL平臺(tái)API中的函數(shù)來(lái)解決的射赛。此外多柑,平臺(tái)API還提供了為OpenCL創(chuàng)建上下文的函數(shù)奶是。OpenCL的上下文規(guī)定了OpenCL應(yīng)用程序的打開方式(相當(dāng)是CUDA中核函數(shù)的調(diào)用)楣责,這可以在宿主機(jī)程序代碼中得到驗(yàn)證。
2.2 運(yùn)行時(shí)API
平臺(tái)API提供函數(shù)創(chuàng)建好上下文之后聂沙,運(yùn)行時(shí)API主要提供使用上下文提供的功能滿足各種應(yīng)用需求的函數(shù)秆麸。這是一個(gè)規(guī)模龐大且內(nèi)容十分復(fù)雜的函數(shù)集。運(yùn)行時(shí)API的第一個(gè)任務(wù)是創(chuàng)建一個(gè)命令隊(duì)列及汉。命令隊(duì)列與設(shè)備相關(guān)聯(lián)沮趣,而且一個(gè)上下文中可以同時(shí)存在多個(gè)活動(dòng)的命令隊(duì)列。有了命令隊(duì)列坷随,就可以通過調(diào)用運(yùn)行時(shí)API提供的函數(shù)來(lái)進(jìn)行內(nèi)存對(duì)象的定義以及管理內(nèi)存中的對(duì)象所依賴的所有其他對(duì)象房铭。以上是內(nèi)存對(duì)象的持有操作驻龟,另外還有釋放操作,也是由運(yùn)行時(shí)API提供的缸匪。
此外翁狐,運(yùn)行時(shí)API還提供了創(chuàng)建動(dòng)態(tài)庫(kù)所需要的程序?qū)ο蟮暮瘮?shù),正是這些動(dòng)態(tài)庫(kù)實(shí)現(xiàn)了Kernel的定義凌蔬。最后露懒,運(yùn)行時(shí)層的函數(shù)會(huì)發(fā)出與命令隊(duì)列交互的命令。此外砂心,管理數(shù)據(jù)共享和對(duì)內(nèi)核的執(zhí)行加以限制同步點(diǎn)也是由運(yùn)行時(shí)API處理的懈词。
2.3 內(nèi)核編程語(yǔ)言
內(nèi)核編程語(yǔ)言是用于編寫OpenCL內(nèi)核代碼的。除了宿主機(jī)程序之外辩诞,內(nèi)核程序也十分重要坎弯,它負(fù)責(zé)完成OpenCL中的實(shí)際工作。在部分OpenCL實(shí)現(xiàn)中用戶可以跟其他語(yǔ)言編寫的原生內(nèi)核實(shí)現(xiàn)交互译暂,但多數(shù)情況下內(nèi)核是需要用戶使用內(nèi)核編程語(yǔ)言編寫實(shí)現(xiàn)的荞怒。OpenCLC編程語(yǔ)言就是OpenCL中的內(nèi)核編程語(yǔ)言,該編程語(yǔ)言是“ISO C99 標(biāo)準(zhǔn)”的一個(gè)擴(kuò)展子集秧秉,也就是說它是由 ISO C99語(yǔ)言派生而來(lái)的『肿溃現(xiàn)在的OpenCL2.1還支持C++,是基于eISO/IEC JTC1 SC22 WG21 N3690(C++14)象迎。
2.4 適合平臺(tái)
-
AMD
根據(jù)AMD官網(wǎng)所提供的內(nèi)容荧嵌,OpenCL在AMD顯卡中只能適用X86核心的CPU架構(gòu),而對(duì)其他PowerPC和ARM架構(gòu)則不適用砾淌;并且也不是所有的AMD顯卡都能運(yùn)行OpenCL啦撮,按其官網(wǎng)介紹只能是AMD Radeon、AMD FirePro和AMD Firestream三種類型的顯卡汪厨;但對(duì)于操作系統(tǒng)則可以是Linux或Windows的系統(tǒng)赃春,如表1所示。
表 1 AMD OpenCL
CPU架構(gòu) | 顯卡類型 | 操作系統(tǒng) | 系統(tǒng)位數(shù) |
---|---|---|---|
X86 | AMD Radeon | Linux/ Windows | 32/64 |
AMD FirePro | Linux/ Windows | 32/64 | |
AMD Firestream | Linux/ Windows | 32/64 |
-
NVIDIA
NVIDIA OpenCL是一種運(yùn)行于具有CUDA能力GPU上的一種底層API劫乱,即OpenCL是運(yùn)行于CUDA之上的一種API织中,從而若適用CUDA的平臺(tái),也同樣適用OpenCL衷戈。根據(jù)NVIDIA官網(wǎng)最新版本的CUDA
7.5適合的平臺(tái)如表 2所示狭吼。
表 2 NVIDIA OpenCL
操作系統(tǒng) | CPU架構(gòu) | Distribution |
---|---|---|
Windows | X86_64 | 10、8.1殖妇、7刁笙、Server 2012 R2、Server 2008 R2 |
Linux | X86_64 | Fedora、OpenSUSE疲吸、RHEL座每、CentOS、SLES摘悴、steamOS尺栖、Ubuntu. |
ppc64le | Ubuntu | |
Mac OSX | x86_64 | 10.11、10.10烦租、10.9 |
3. 計(jì)算架構(gòu)
OpenCL 的設(shè)計(jì)目標(biāo)是為開發(fā)人員提供一套移植性強(qiáng)且高效運(yùn)行的解決方案延赌。為了更好的描述OpenCL設(shè)計(jì)的核心理念,Khronos Group官方將OpenCL的計(jì)算架構(gòu)分解成四個(gè)模型叉橱,分別平臺(tái)模型(Platform Model)挫以、內(nèi)存模型(Memory Model)、執(zhí)行模型(Execution
Model)以及編程模型(Programming Model)窃祝。
3.1 平臺(tái)模型(Platform Model)
從整體上來(lái)看掐松,主機(jī)(host)端是負(fù)責(zé)掌管整個(gè)運(yùn)算的所有計(jì)算資源,因此OpenCL 應(yīng)用程序首先是由主機(jī)端開始粪小,然后由程序?qū)⒏鱾€(gè)計(jì)算命令從主機(jī)端發(fā)送給每個(gè) GPU 設(shè)備處理單元大磺,運(yùn)行完畢之后最后由主機(jī)端結(jié)束。
平臺(tái)模型如圖 16所示探膊。從圖中可以直觀的看到杠愧,最基本處理單位是Processing Element,簡(jiǎn)稱PE(處理單元)逞壁,而一個(gè)或多個(gè)PE組成了Compute Unit流济,簡(jiǎn)稱CU(計(jì)算單元),進(jìn)而一個(gè)或多個(gè)CU就組成了Compute Device腌闯,即OpenCL設(shè)備绳瘟。最后,一個(gè)或多個(gè)OpenCL設(shè)備連接到主機(jī)姿骏,并等待著處理主機(jī)發(fā)送的計(jì)算指令糖声,由于PE是最基本處理單位,因此每條計(jì)算指令最終都?xì)wPE進(jìn)行處理分瘦,而PE是在CU中的蘸泻。
3.2 內(nèi)存模型(Memory Model)
OpenCL將內(nèi)核程序中用到的內(nèi)存分為圖 17所示的四種不同的類型。
其中它們的讀寫特性分別為:
-
Global memory:
工作區(qū)內(nèi)的所有工作節(jié)點(diǎn)都可以自由的讀寫其中的任何數(shù)據(jù)擅腰。OpenCL
C語(yǔ)言提供了全局緩存(Global buffer)的內(nèi)建函數(shù)蟋恬。 -
Constant memory:
工作區(qū)內(nèi)的所有工作節(jié)點(diǎn)可以讀取其中的任何數(shù)據(jù)但不可以對(duì)數(shù)據(jù)內(nèi)容進(jìn)行更改翁潘,在內(nèi)核程序的執(zhí)行過程中保持不變趁冈。主機(jī)端負(fù)責(zé)分配和初始化常量緩存(Constant buffer)。 -
Local memory:
只有同一工作組中的工作節(jié)點(diǎn)才可以對(duì)該類內(nèi)存進(jìn)行讀寫操作。它既可以為 OpenCL的執(zhí)行分配一塊私有內(nèi)存空間渗勘,也可以直接將其映射到一塊全局緩存(Global buffer)上沐绒。特點(diǎn)是運(yùn)行速度快。 -
Private memory:
只有當(dāng)前的工作節(jié)點(diǎn)能對(duì)該內(nèi)存進(jìn)行訪問和讀寫操作旺坠。一個(gè)工作節(jié)點(diǎn)內(nèi)部的私有緩存(Private buffer)對(duì)其他節(jié)點(diǎn)來(lái)說是不可見的乔遮。
表 3 OpenCL各種存儲(chǔ)器的分配方式和訪問權(quán)限
存儲(chǔ)器類型 | 主機(jī) | 內(nèi)核 | ||
---|---|---|---|---|
分配方式 | 訪問權(quán)限 | 分配方式 | 訪問權(quán)限 | |
Global | 動(dòng)態(tài)分配 | 可讀、可寫 | 不可分配 | 可讀取刃、可寫 |
Constant | 動(dòng)態(tài)分配 | 可讀蹋肮、可寫 | 靜態(tài)分配 | 只讀 |
Local | 動(dòng)態(tài)分配 | 不可訪問 | 靜態(tài)分配 | 可讀、可寫 |
Private | 不可分配 | 不可訪問 | 靜態(tài)分配 | 可讀璧疗、可寫 |
3.3 執(zhí)行模型(Execution Model)
OpenCL的執(zhí)行模型是應(yīng)用程序通過主機(jī)端對(duì)OpenCL設(shè)備端上的內(nèi)核程序進(jìn)行管理坯辩,該模型分為兩個(gè)模塊:一個(gè)是在主機(jī)端執(zhí)行的管理程序,也稱為Hostprogram崩侠,另一個(gè)是主機(jī)端的Hostprogram所管理的在OpenCL上執(zhí)行的程序漆魔,也被稱作Kernels。在執(zhí)行Kernels前却音,先要建立一個(gè)索引空間改抡,來(lái)對(duì)設(shè)備里的每個(gè)節(jié)點(diǎn)進(jìn)行標(biāo)識(shí),每個(gè)節(jié)點(diǎn)都將執(zhí)行相同的kernel程序系瓢。在每個(gè)工作組中阿纤,都有一個(gè)局ID,每個(gè)節(jié)點(diǎn)在全局里還有個(gè)全局ID夷陋,OpenCL使用NDRange來(lái)定義這個(gè)索引空間阵赠。
如圖 18所示的OpenCL執(zhí)行模型,其過程可以細(xì)分為如下的步驟完成:
- 查詢連接主機(jī)上的OpenCL設(shè)備肌稻;
- 創(chuàng)建一個(gè)關(guān)聯(lián)到OpenCL設(shè)備的context清蚀;
- 在關(guān)聯(lián)的設(shè)備上創(chuàng)建可執(zhí)行程序;
- 從程序池中選擇kernel程序爹谭;
- 從主機(jī)或設(shè)備上創(chuàng)建存儲(chǔ)單元枷邪;
- 如果需要將主機(jī)的數(shù)據(jù)復(fù)制到OpenCL設(shè)備上的存儲(chǔ)單元上;
- 執(zhí)行kernel程序執(zhí)行诺凡;
- 從OpenCL設(shè)備上復(fù)制結(jié)果到主機(jī)上东揣。
3.4 編程模型(Programming Model)
OpenCL支持兩種編程模型,分別為數(shù)據(jù)并行編程模型和任務(wù)并行編程模型腹泌,并支持上面由這兩種編程模型混合的混合編程模型嘶卧。
-
數(shù)據(jù)并行編程模型
OpenCL提供一個(gè)分層的數(shù)據(jù)并行編程模型,即典型的SIMD計(jì)算模型凉袱,其特點(diǎn)是每個(gè)數(shù)據(jù)經(jīng)由同樣的指令序列處理芥吟,而處理數(shù)據(jù)的次序是不確定的侦铜,并且每個(gè)數(shù)據(jù)的處理是不相干的,即任一線程的計(jì)算不得依賴于其它線程的結(jié)果(包括中間結(jié)果)钟鸵。 -
任務(wù)并行編程模型
任務(wù)并行模型中的每個(gè)內(nèi)核是在一個(gè)獨(dú)立的索引空間中執(zhí)行的钉稍,也就是說,執(zhí)行內(nèi)核的計(jì)算機(jī)單元內(nèi)只有一個(gè)工作組棺耍,其中只有一個(gè)工作項(xiàng)贡未。在這樣的模型中,每個(gè)線程都可以執(zhí)行不同的帶啊蒙袍,著相當(dāng)于MIMD的計(jì)算模型俊卤,適合多核心CPU。