就像大一學C++,大二學匯編一樣,我也寫弄了些個月的CUDA,然后,想想,應該開始刨根問底地,去學點在CUDA之下層的東西,可能會對異構這個編程了解的多。
1 簡介
OpenCL全稱:開發計算語言,是並行程序的開發標准,使用與任何異構平台——包括多CPU、GPU、CPU與GPU結合等。OpenCL由Khronos Group維護。
OpenCL是一個用於異構平台上編程的開放性行業標准。這個平台可以包括 CPU GPU和其他各類計算設備,例如 DSP和Cell/B.E.等等。
OpenCL和CUDA的關系很和諧,前者是異構編程規范標准,后者是英偉達基於OpenCL之上開發的一個更面向程序員的GPUAPI。所以,OpenCL適合於包括英偉達和AMD等的顯卡
程序開發。
2 認識OpenCL的框架
2.1 平台模型
[1個host]-[1..N個device] (主機:host;設備:device)
[1個device]-[1..N個CU] (計算單元:CU)
[1個CU]-[1..N個PE] (處理單元:PU)
host端管理者整個平台的所有計算資源,應用程序會從host端向各個 OpenCL設備的處理單元發送計算命令。在一個計算單元內的所有處理單元會執行完全相同的一套指令
流程。指令流可以是 SIMD模式或者SPMD模式。所有由OpenCL編寫的應用程序都是從Host啟動並結束,最終的計算都發生在PE中。
2.2 內存模型
內存介紹:
全局內存 (global memory):工作空間內所有的工作節點都可以讀寫此類內存中的任意元素。OpenCL C提供了緩存global buer的內建函數。
常量內存 (constant memory):工作空間內所有的工作節點可以只讀此類內存中的任意元素。 host負責分配和初始化 constant buer,在內核執行過程中保持不變。
局部內存 (local memory):從屬於一個工作組的內存,同一個工作組中所有的工作節點都可以共享使用該類內存。其實現既可以為 OpenCL執行為其分配一塊專有內存空間,
也有可能直接將其映射到一塊global buer上。
私有內存 (private memory):只從屬於當前的工作節點。一個工作節點內部的private buer其他節點是完全不可見的。
在這點上,基本上和CUDA介紹的內存是一樣的。這里的局部內存和CUDA的私有變量差不多一個概念。
內存使用:
在內存的使用上,有兩種方式:內存拷貝和內存映射。
拷貝數據是指host通過相應的OpenCL API將數據從host寫入到OpenCL設備的內存中或者從 OpenCL設備內存讀出數據到 host內存中。
內存映射方法允許用戶通過相應 OpenCLAPI將OpenCL的內存對象映射到 host端可見的內存地址空間中。映射之后用戶就可以在 host端的映
射地址讀寫該內存了,在讀寫完成之后用戶必須使用對應 API解除這種映射關系。同拷貝內存方式一樣,映射內存也分block和non-block模式。
2.3 執行模型
OpenCL的執行模型可以分為兩部分,一部分是在 host上執行的主程序(host program),另一部分是在 OpenCL設備上執行的內核程序(kernels),OpenCL通過主程序來
定義上下文並管理內核程序在OpenCL設備的執行。
執行模式最重要的是分配線程網絡,這點和CUDA是一回事,可以引用。
2.4 編程模型
OpenCL支持按數據並行的編程模型和按任務並行的編程模型。
數據並行模型是指同一系的列指令會作用在內存對象的不同元素上,即在不同內存元素上按這個指令序列定義了統一的運算。
在任務並行編程模型是指工作空間內的每個工作節點在執行 kernel程序時相對於其他節點是絕對獨立的。在這種模式下對每個工作節點都相當於工作在一個單一的計算單
元內,該單元內只有單一工作組,該工作組中只有該節點本身在執行。用戶可以通過如下方法實現按任務並行:
-使用OpenCL設備支持的向量類型數據結構
-同時執行或選擇性執行多個kernels
-在執行kernels同時交叉性執行一些native kernels程序
OpenCL提供了兩個領域的同步:
-在同一個工作組中所有的工作節點之間的同步
-同一個上下文中不同的 command queues之間和同一個 command queue的不同commands之間的同步
從CUDA了解openCL是在閱讀和理解相關CUDA編程知識后,在讀《OpenCL中文教程》的一個第一章和第二章的知識匯總,去掉了CUDA編程指南中講解的雷同知識。在了解和
明白OpenCL是怎么一回事兒后,我將開始openCL的Hello world了,雖然,僅僅一個helloword可能沒什么意義,但是,象征性的程序必須寫起來。