OpenCL 教學(一)
文章推薦指數: 80 %
OpenCL 是由Khronos Group 針對異質性計算裝置(heterogeneous device)進行平行化運算所設計的標準API 以及程式語言。
所謂的「異質性計算裝置」,是 ...
Hotball'sHiveSearchthissite
NavigationHomeSitemapOpenCL
連結BlogMail
OpenCL>
OpenCL教學(一)
Contents1OpenCL簡介2OpenCL的架構3OpenCL環境設定4開始撰寫OpenCL程式5建立CommandQueue6產生資料7配置記憶體並複製資料8編譯OpenCLkernel程式9執行OpenCLkernelOpenCL簡介OpenCL是由KhronosGroup針對異質性計算裝置(heterogeneousdevice)進行平行化運算所設計的標準API以及程式語言。
所謂的「異質性計算裝置」,是指在同一個電腦系統中,有兩種以上架構差異很大的計算裝置,例如一般的CPU以及顯示晶片,或是像CELL的PPE以及SPE。
目前,最為常見的就是所謂的GPGPU應用,也就是利用一般的顯示晶片(即GPU)進行3D繪圖以外的計算工作。
過去GPGPU的應用,有各種不同的使用方式。
最早的GPGPU,多半是直接透過3D繪圖的API進行,例如OpenGL或D3D的HLSL(HighLevelShadingLanguage)。
但是,這樣做有很多缺點,主要是即使想要進行的運算和3D繪圖無關,仍需要處理很多3D繪圖方面的動作(例如建立texture,安排render-to-texture動作等等)。
這讓GPGPU變得十分複雜。
後來開始有些嘗試把這些3D繪圖部份隱藏起來的想法,例如由Stanford大學設計的BrookGPU,可以透過不同的backend將Brook程式轉換成由CPU、Direct3D、或OpenGL來執行。
另外,也有各家顯示卡廠商自行開發的系統,包括ATI針對其產品設計的ClosetoMetal(以及後來的AMDStream),以及NVIDIA的CUDA。
Microsoft也在DirectX11中加入了特別為GPGPU設計的DirectCompute。
由於各家廠商的GPGPU方案都是互不相容的(例如AMDStream的程式無法在NVIDIA的顯示晶片上執行,而CUDA的程式也不能在AMD的顯示晶片上執行),這對GPGPU的發展是不利的,因為程式開發者必須為不同廠商的顯示晶片分別撰寫程式,或是選擇只支援某個顯示晶片廠商。
由於顯示晶片的發展愈來愈彈性化,GPGPU的應用範圍也增加,因此Apple決定提出一個統一的GPGPU方案。
這個方案得到包括AMD、IBM、Intel、NVIDIA等相關廠商的支持,並很快就交由KhronosGroup進行標準化。
整個計畫只花了五個月的時間,並在2008年十二月時正式公開。
第一個正式支援OpenCL的作業系統是Apple的MacOSX10.6"SnowLeopard"。
AMD和NVIDIA也隨後推出了在Windows及Linux上的OpenCL實作。
IBM也推出了支援CELL的OpenCL實作。
OpenCL的主要設計目的,是要提供一個容易使用、且適用於各種不同裝置的平行化計算平台。
因此,它提供了兩種平行化的模式,包括taskparallel以及dataparallel。
目前GPGPU的應用,主要是以dataparallel為主,這裡也是以這個部份為主要重點。
所謂的dataparallel,指的是有大量的資料,都進行同樣的處理。
這種形式的平行化,在很多工作上都可以見到。
例如,影像處理的程式,經常要對一個影像的每個pixel進行同樣的動作(例如Gaussianblur)。
因此,這類工作很適合dataparallel的模式。
OpenCL的架構OpenCL包括一組API和一個程式語言。
基本上,程式透過OpenCLAPI取得OpenCL裝置(例如顯示晶片)的相關資料,並將要在裝置上執行的程式(使用OpenCL程式語言撰寫)編繹成適當的格式,在裝置上執行。
OpenCLAPI也提供許多裝置控制方面的動作,例如在OpenCL裝置上取得一塊記憶體、把資料從主記憶體複製到OpenCL裝置上(或從OpenCL裝置上複製到主記憶體中)、取得裝置動作的資訊(例如上一個程式執行所花費的時間)等等。
例如,我們先考慮一個簡單的工作:把一群數字相加。
在一般的C程式中,可能是如下:floata[DATA_SIZE];floatb[DATA_SIZE];floatresult[DATA_SIZE];//...for(inti=0;i
接著,要先取得系統上所有的OpenCLplatform。
在MacOSX10.6下,目前只有一個由Apple提供的OpenCLplatform,但是在其它系統上,可能會有不同廠商提供的多個不同的OpenCLplatform,因此需要先取得platform的數目:cl_interr;cl_uintnum;err=clGetPlatformIDs(0,0,&num);if(err!=CL_SUCCESS){std::cerr<platforms(num);err=clGetPlatformIDs(num,&platforms[0],&num);if(err!=CL_SUCCESS){std::cerr<(platforms[0]),0};cl_contextcontext=clCreateContextFromType(prop,CL_DEVICE_TYPE_DEFAULT,NULL,NULL,NULL);if(context==0){std::cerr<devices(cb/sizeof(cl_device_id));clGetContextInfo(context,CL_CONTEXT_DEVICES,cb,&devices[0],0);CL_CONTEXT_DEVICES表示要取得裝置的列表。
和前面取得platformID的情形相同,clGetContextInfo被呼叫了兩次:第一次是要取得需要存放裝置列表所需的記憶體空間大小(也就是傳入&cb),然後第二次呼叫才真正取得所有裝置的列表。
接下來,可能會想要確定倒底找到的OpenCL裝置是什麼。
所以,可以透過OpenCLAPI取得裝置的名稱,並將它印出來。
取得和裝置相關的資料,是使用clGetDeviceInfo函式,和前面的clGetContextInfo函式相當類似。
以下是取得裝置名稱的方式:clGetDeviceInfo(devices[0],CL_DEVICE_NAME,0,NULL,&cb);std::stringdevname;devname.resize(cb);clGetDeviceInfo(devices[0],CL_DEVICE_NAME,cb,&devname[0],0);std::cout<#include
建立成功後,再呼叫clBuildProgram函式編譯程式。
clBuildProgram函式可以指定很多參數,不過在這裡暫時沒有使用到。
有了這個函式,在main函式中,直接呼叫:cl_programprogram=load_program(context,"shader.cl");if(program==0){std::cerr<#include
延伸文章資訊
- 1TensorFlow採用OpenCL後端使GPU推理效能加倍 - iThome
OpenCL的設計更適合用於各種計算加速器,因此以OpenCL後端處理行動裝置GPU推理工作負載,比OpenGL後端效能好上許多.
- 2OpenCL | NVIDIA Developer
OpenCL™ (Open Computing Language) is a low-level API for heterogeneous computing that runs on CUD...
- 3[OpenCL]OpenCL 總整理 - HackMD
[OpenCL]OpenCL 總整理=== ## 安裝[install packets](https://askubuntu.com/a/850594/655911) ## 編譯[what is.
- 4OpenCL Overview - The Khronos Group Inc
OpenCL™ (Open Computing Language) is an open, royalty-free standard for cross-platform, parallel ...
- 5AI運算加速系列-OpenCL 高效能平行運算實作班(資展國際)
深度學習OpenCL (Open Computing Language)是基於C及C++語言,以同一種語言實現跨越CPUs、GPUs、CELL、DSP等異質(heterogeneous)執行平台...