1. 程式人生 > >OpenCL-1-程式設計四大模型介紹

OpenCL-1-程式設計四大模型介紹

本節介紹OpenCL的四個程式設計模型。

0.前言

  OPenCL作為開放性的異構計算的標準,支援的平臺有CPU、GPU、DSP、FPGA。支援的裝置如此不同,那麼需要對它們有一個統一的分層、模型劃分,才能讓各家更好的實現–平臺模型、執行模型、記憶體模型、程式設計模型。

1.平臺模型

  • OpenCL裝置有兩部分組成,宿主機和OpenCL裝置
    • 宿主機負責整體流程控制,一般為CPU。
    • OpenCL裝置主要負責資料運算操作。
  • OpenCL裝置內部由多個計算單元(CU)組成,每一個CU可以繼續劃分為處理單元(PU)。
  • 執行流程: 宿主機負責管理所有的OpenCL裝置,宿主機發起計算任務,選擇特定的OpenCL裝置並建立計算環境。然後將計算任務和資料傳送給OPenCL裝置。裝置呼叫內部計算單元進行計算,完成後將結果返還給宿主機,該次計算任務結束。

2.執行模型

2.1執行模型概念

  OPenCL是一個主從處理模型,根本是宿主機如何利用OpenCL裝置上大量的計算資源進行有效計算。所以OpenCL執行模型的任務就是如何高效地呼叫這些計算資源
* 宿主機將每一個處理單元(PE)分配一個索引號,這個唯一的索引號稱為全域性ID(Global ID),全體PE被看做一個工作空間的work-item。
* 因為我們可能處理陣列、圖形乃至三維影象,所以對應的工作空間也可以定義為一維、二維、三維。
* 為了更好的處理不同的資料,我們可以將工作空間進行粗粒度的劃分,如將一部分ID劃分到一組,這個組稱為work-group,每一個組內也可以分配ID,不過這個ID稱為區域性ID(Local ID)。全域性ID和區域性ID存在對映關係。
* OpenCL規範中使用一個長度為N的整數陣列來描述工作空間的大小(N<=3)。陣列中的數值對應相應維度上工作點的個數。
* 如果將我們常見的三維魔方想象成一個工作空間,那麼一維即為紅色的一行,即一維個數為3,二維為紅色那個面,二維個數為9,三維即為整個工作空間,三維個數為27。

魔方

2.2上下文

  計算工作主要在OpenCL裝置上進行,但宿主機也扮演著非常重要的角色。宿主機主要通過上下文(Context)管理OpenCL裝置。上下文指的是所管理硬體和軟體資源,如下所示:
* 裝置:OpenCL程式呼叫的計算裝置
* 核心:在計算裝置上執行的並行程式。
* 程式物件:核心程式的原始碼(.cl檔案)和可執行檔案。
* 記憶體物件:計算裝置執行OpenCL程式所需的變數。
上下文由宿主機使用API進行建立、管理、銷燬。

2.3命令佇列

  宿主機主要通過命令對相應裝置進行控制。根據計算量的大小,計算裝置並不能立刻執行完被分配的計算任務。那麼宿主機只能等著計算裝置把任務計算完了才能繼續分配新的任務麼?顯然不是,每一個計算裝置都會有一個命令佇列。命令佇列只能管理一個計算裝置

。通過命令佇列,就實現了宿主機和計算裝置的非同步控制與執行。

  佇列中的命令主要有三種:
* 啟動命令:OpenCL裝置開始執行核心程式。
* 記憶體命令:在宿主機與記憶體裝置之間移動資料,或者在兩者之間進行記憶體對映。
* 同步命令:約束命令在計算裝置上的執行:
* 亂序執行: 命令按照在命令佇列中的順序進行發射,但不保證計算裝置是按照這個順序進行執行的。
* 有序執行: 命令按照在命令佇列中的順序進行發射和執行,上一條命令執行完成後才能發射下一條命令。

  宿主機程式可以為一個計算裝置建立多個命令佇列–一個計算裝置可以有多個命令佇列。這些命令佇列沒有關聯。這也就意味著一個計算裝置可以執行多個種類的任務,如小明可以在等待遊戲載入的事件背幾個英語單詞 ~_~。

3.儲存模型

  與通用計算程式的記憶體物件相似,OpenCL將裝置中的儲存器抽象成四層結構的儲存模型:
* 全域性記憶體:工作空間中的所有節點都可以讀寫。(全域性變數)
* 全域性變數:工作空間中的所有節點都可以讀,但不可以寫。(全域性常量)
* 本地記憶體:同一個工作組中的工作節點可以進行讀寫,對其他工作組不可見。不能通過宿主機進行初始化。(當前檔案的全域性變數)
* 私有記憶體:只屬於工作節點。(函式中的區域性變數)

記憶體模型

在程式執行期間,需要宿主機和計算裝置進行資料交換,存在兩種方式:
* 資料拷貝進行:將需要的資料拷貝到工作組空間,計算完成後再拷貝出去(傳形參)
* 記憶體對映:將需要計算資料的地址傳進去(傳指標)

4.程式設計模型

  前面已經提到計算的時候可以按照兩種模型來進行計算:資料並行和任務並行。
* 資料並行:將需要計算的資料進行等分,分配給不同的計算裝置進行計算。如需要進行兩個很大矩陣的求和運算,那麼就可以將矩陣資料分成幾份,那麼理論上計算事件縮減為原來的1/N。這適用與資料想關聯不大的計算任務。
* 任務並行:如計算資料量不大,但每一個步驟前後依賴,如你必須先將水燒開才能下面條,如果你需要不斷的煮麵條,那麼就可以將這個過程分成階段,用好幾個鍋同時進行。具體細節參考工廠的流水線工作模式。

  既然有資料或任務的並行,那麼同步就成為一個繞不開的節點。並行是指在計算裝置執行核心的過程中,對於其他的節點是絕對獨立的,互不影響。OpenCL有三種方式進行同步:
* 同一個work-group的節點間進行資料同步。
* 同一個命令佇列中的命令進行同步
* 同一個上下文中的命令佇列進行同步。

更多博主原創文章,請移步: