這一章主要討論Opencl標準中的關鍵概念和在手機平臺上開發Opencl程序的基礎知識。若是想知道關於Opencl更詳細的知識,請查閱參考文獻中的《The OpenCL Specification》。對於已經有OpenCL的基礎知識和經驗的開發者能夠跳過這一章,直接跳到下一章閱讀便可。編程
Opencl是由Khronos group開發和維護的一個開源的和徹底免費的標準,針對是如何在異構系統上進行跨平臺的程序並行。OpenCL設計理念是幫助開發者利用最新的異構系統的巨大的計算能力,並使跨平臺的應用開發變的容易。架構
驍龍平臺上使用的高通Adreno GPU系列是最先全面支持Opencl的手機GPU之一。分佈式
圖2-1 使用Opencl的異構系統函數
圖2-1表示了一個支持Opencl的典型異構系統。這個系統包含了3個主要部分:性能
最近這些年,手機的片上系統(SOCs)已經在計算能力、複雜度和功能性上取得了顯著的進步。手機SOCs上的GPU(手機的GPU)是很是強大的,某些頂級的手機GPU的原始計算能力可以達到控制檯/分佈式GPU(電腦的GPU)的水平。測試
開發者將面臨這樣的挑戰:如何有效的利用GPU如此強大的計算能力,如何在不知道GPU的底層實現細節的狀況下快速開發應用程序,同時能保持應用程序在不一樣SOCs上兼容性?優化
OpenCL的創造就是爲了解決上面的問題,OpenCL的跨平臺支持可以讓開發者很方便的利用手機SOCs上的計算能力。經過使用OpenCL,許多領域的高級用例可以方便的在手機SOCs上使用,好比圖像/音頻處理,計算機視覺和機器視覺等。spa
在高通,在Andreno GPUs上使用OpenCL已經成功加速了許多案例,也展現了出色的性能、功耗和可移植行。針對在驍龍SOCs上開發的應用程序,強烈建議在GPU上使用OpenCL使其加速。翻譯
OpenCL標準主要包兩個方面:OpenCL的實時運行的API 和OpenCL的C語言規範(就是.cl文件)。API定義了一系列運行在Host上的函數,主要包括資源管理,內核分發(將kernel函數分發到不一樣的GPU上運行)以及許多其餘的任務;OpenCL的C語言是用來寫kernel函數的,kernel函數是運行在OpenCL設備(OpenCL設備參見圖2-1)上。API和C語言將會在接下來的章節中說明。設計
(對照圖2-1,OpenCL就是定義一些API,這些運行在主CPU上,將任務劃分紅一個個的kernel函數,將kernel函數分發到OpenCL設備上運行。)
OpenCL的API函數能夠分紅兩種,平臺層和實時運行層。表2-1 和表2-2分別總結了平臺層和實時運行的一些高階功能。
表2-1 OpenCL平臺層的功能
功能 |
詳細描述 |
發現平臺 |
檢查當前的OpenCL平臺是否可用 |
發現OpenCL設備 |
在GPU,CPU或者其餘設備上找到可用的OpenCL設備 |
查詢OpenCL設備的信息 |
查詢OpenCL設備信息包括:全局內存大小(global memory size),本地內存大小(local memory size),最大的工做組數量(maximun workgroup size)等。而且檢查該設備支持的擴展功能(OpenCL定義了標準功能和擴展功能)。 |
上下文 |
上下文管理,好比上下文(context)的建立,保留和釋放 |
表2-2 OpenCL的實時運行層的功能
功能 |
詳細描述 |
命令隊列的管理(Command queue) |
命令隊列用於OpenCL設備(好比GPU)和主設備(好比主CPU)之間的通訊,一個應用程序中能夠有多個隊列。 |
建立和編譯OpenCL程序和kernel(內核),(編譯.cl文件) |
檢查kernel是否下載和編譯正確 |
爲kernel準備要執行的數據,建立內存對象,並對其初始化 |
使用什麼樣的內存標誌(好比只讀只寫等)?是否有能直接建立0拷貝的內存(0拷貝在第7章將會詳細說明)? |
建立一個kernel調用,並將它提交到對應的OpenCL設備上 |
使用多大的workgroup(工做組)? |
同步 |
內存同步(須要等OpenCL運行完後再進行結果拷貝)。 |
資源管理 |
傳遞運行結果(將OpenCL設備上運行結果拷貝到主設備)和釋放資源。 |
理解這兩個API層是寫OpenCL應用程序的基本要求。參照參考文檔獲取更多細節信息。
做爲C99 標準的一個子集,OpenCL的C語言是用來寫能編譯和能在設備(之後OpenCL設備就簡稱設備)上運行的kernel函數的。有C語言編程經驗的開發者可以很快上手OpenCL的C語言編程。可是,爲了不一些常見的錯誤,理解C99標準和OpenCL C語言之間的差異也是相當重要的。下面是兩個關鍵的不一樣點:
當前的OpenCL v2.2和臨時SPIR-V 1.2標準包含了許多改進的特性。可參照參考目錄獲取更多細節。
OpenCL定義了兩種profiles(很差翻譯),嵌入式的profiles和完整的profiles。嵌入式的profiles主要是用於手機設備,相比於傳統的計算設備好比臺式機的GPUs,手機設備的計算精度更低,硬件特性更少。參考文檔列出了嵌入式profiles和完整profiles之間的主要不一樣點。
做爲一個被嚴格定義的計算標準,OpenCL有很好的可移植性。若是程序沒有使用任何供應商特有的特性或者平臺特有的擴展或特性,針對一個供應商平臺寫的OpenCL程序能夠很好地在另外一個供應商平臺上運行。
OpenCL程序的兼容性已經被Khronos的驗證程序保證了。若是OpenCL供應商聲稱他們是符合OpenCL標準的,Khronos的驗證程序會要求OpenCL供應商在他們的平臺上經過嚴格的一致性測試。
不像程序的能夠執行,OpenCL的性能並非可移植的。做爲一個高級別的計算標準,OpenCL的硬件實現是取決於供應商的。不一樣的硬件供應商有不一樣的硬件架構,每一種架構都有它本身的優點和劣勢。因此,針對某一個供應商平臺開發和優化的OpenCL的應用程序,在另外一個供應商的平臺上可能不會有一樣的性能
甚至對於同一個供應商,他們的不一樣系列的GPU硬件在微觀架構和特性上都會有所不一樣,這樣也會致使OpenCL程序表現出顯著的性能差別。因此,針對老一代的硬件優化的程序常常須要進行一些調整,來充分發揮新一代硬件的運算能力。
OpenCL可以徹底向後兼容,來保證針對OpenCL舊版本的代碼可以毫無問題的運行在新版本的OpenCL上。不過須要注意,由於有些API函數在新版本已經廢棄不使用了,因此若是包含了OpenCL2.x版本頭文件中而且使用了OpenCL 1.1 或者OpneCL1.2中過期的APIs,那麼須要定義宏 CL_USE_DEPRECATED_OPENCL_1_1_APIS 或者CL_USE_DEPRECATED_OPENCL_1_2_APIS。
OpenCL的擴展並不保證在新的設備上可以繼續使用,因此使用擴展功能的應用程序必須檢查新的設備是否支持他們。