HMPP 開放標準

HMPP 用於異構多核並行程式設計。

OpenHMPP 標準基於一組指令，是用於處理硬體加速器的程式設計模型，但又沒有 GPU 程式設計的相關複雜性。這種基於指令的方法已經實現，因為他們使應用程式程式碼和硬體加速器使用之間形成鬆散關係。

本文涉及組成 OpenHMPP 標準的 HMPP 指令，但並不處理指令的執行連結到指令執行。

簡介

OpenHMPP 基於指令的程式設計模型提供了一種語法，有效地減輕硬體加速器上的計算，最佳化資料向 / 從硬體儲存器移動。

模型基於 CAPS (編譯器和超標量體系結構以及嵌入式處理器) 的初始化工作，以及來自 INRIA, CNRS, 雷恩第一大學和雷恩 INSA 的共同專案。

OpenHMPP 標準概念

OpenHMPP 標準基於 codelets 的概念，可以在硬體上遠端執行。

2.1 OpenHMPP Codelet 概念

codelet 具有以下屬性:

它是一個純函式。
* 它不包含靜態或不穩定的變數宣告，也不涉及任何全域性變數，除非這些已經由 HMPP “resident” 指令所宣告
* 它不包含任何具有無形體 (不能內聯) 的函式呼叫。這包含庫和系統函式的使用，例如 malloc, printf, ...

* 每個函式必須引用靜態純函式 (沒有函式指標)。
它不返回任何值 (C 中的 void 函式或 FORTRAN 子程式)。
引數的數量應該是固定的 (即沒有像 C 中的 vararg 那樣可變數量的引數)。
它不是遞迴的。
它的引數設定為 non-aliased。
它不包含 callsite 指令 (即 RPC 至另一個 codelet) 或其他 HMPP 指令。

這些屬性確保 codelet RPC 可以透過硬體遠端執行。此 RPC 及其相關的資料傳輸可以是非同步的。

2.2 Codelet RPCs

HMPP 提供同步和非同步的 RPC。非同步操作的執行依賴於硬體。

2.3 HMPP 儲存器模型

HMPP 考慮到兩個地址空間：一個主機處理器和硬體儲存器。

2.4 指令概念

OpenHMPP 指令可能被視為 “元資訊” 新增到應用程式原始碼。它們是安全的元資訊，即不會改變原始程式碼的行為。它們處理函式的遠端執行 (RPC)，以及資料向 / 從硬體儲存器傳輸。

下表介紹了 OpenHMPP 指令。OpenHMPP 指令滿足不同需求：其中一些專門用於宣告，其他用於執行的管理。

2.5 指令集的概念

HMPP 方法的基本點之一是指令的概念及其關聯的標籤，使它能夠在分佈於應用程式中的整個指令集上公開一個相干結構。

有兩種型別的標籤:

一類關聯到 codelet。攜帶這種標籤的指令一般僅限於管理一個 (在文件 的其餘部分稱為 stand-alone，以便從一組 codelet 中區分開)。
一類關聯到一組 codelets。這些標籤說明如下: ““, 其中 “LabelOfGroup” 是由使用者指定一個名稱。 具有這種標籤的指令一般涉及到整個組。組的概念是保留給這樣一類問題，即要求對整個應用程式的資料做具體管理以獲取效能。

2.6 OpenHMPP 指令語法

為了簡化符號，正則表示式 將用於描述 HMPP 指令的語法。

下面的顏色通常用於描述指令的語法:

保留的 HMPP 關鍵字是藍色； 在 HMPP 關鍵字中可以被減少的基本語法是紅色； 使用者變數仍然為黑色。

2.6.1 一般語法

OpenHMPP 指令的一般語法如下:

C 語言:
pragma hmpp grplabel> codeletlabel? directivetype ,directiveparameters* &
FORTRAN 語言:

$hmpp grplabel> codeletlabel? directivetype ,directiveparameters* &

其中:

: 是命名一組 codelets 的唯一識別符號。在應用程式中沒有組被定義的情況下，這個標籤可以簡單地略過。Legal 標籤必須遵循此語法: a-z,A-Z,a-z,A-Z,0-9,*。請注意 “” 字元屬於語法，且對這類標籤是強制性的。
codeletlabel: 是命名一個 codelet 的唯一識別符號。Legal 標籤必須遵循此語法: a-z,A-Z,a-z,A-Z,0-9,directive: 是指令的名稱； directiveparameters: 指定一些指令相關聯的引數。這些引數可能是不同型別並指定 給指令的某些引數或執行的一種模式 (例如同步與非同步);
&: 是用於在下一行繼續該指令的字元 (C 和 FORTRAN 都是相同的)。

2.6.2 指令引數

關聯到一個指令的引數可能是不同型別。以下是 在 HMPP 中定義的指令引數:

version = major.minor.micro: 由預處理器指定 HMPP 指令的版本。
argsarg_items.size={dimsize,dimsize*}: 指定一個非標量引數 (陣列) 的大小。
argsarg_items.io=inout: 表示指定函式引數是輸入，輸出或兩者兼而有之。預設情況下，非限定引數為輸入。
cond = "expr": 指定組或 codelets 開始執行的一個條件 C 或 Fortran 布林表示式的值為是 C 或 Fortran 布林表示式的值為 true。
target=targetname:targetname*: 指定是哪個 target 以嘗試使用給定的順序。
asynchronous: 指定不阻止 codelet 的 執行 (預設是同步的)。
args.advancedload=true: 表明指定的引數是預載入的。只有 in 或 inout 引數可以被預載入。
argsarg_items.noupdate=true: 此屬性指定 硬體上的資料已經可用，因此不需要轉換。 當設定了此屬性時，所考慮的引數沒有任何傳遞。
args.addr="": 是一個表示式，給出了資料上載的地址。
args.const=true: 表示引數只要上載一次。

OpenHMPP 指令

3.1 宣告和執行一個 codelet 的指令

codelet 指令宣告在硬體加速器上遠端執行計算。

codelet 指令:

codelet 標籤是強制性的並且在應用程式中是唯一的
如果沒有組被定義則不需要組標籤。
Codelet 指令在函式宣告之前插入。

該指令的語法是:

pragma hmpp grplabel> codeletlabel codelet

, version = major.minor.micro??

, argsargitems.io=inout , argsargitems.size={dimsize,dimsize*} , argsarg_items.const=true , cond = "expr"

, target=targetname:targetname

可以在一個函式中加入多個 codelet 指令，以便指定不同用途或不同執行文字。但是，一個給定呼叫站點標籤只能有一個 codelet 指令。

Callsite 指令指定程式內的給定點如何使用一個 codelet。

該指令的語法是:

pragma hmpp grplabel> codeletlabel callsite

, asynchronous?

, argsargitems.size={dimsize,dimsize*} , argsargitems.advancedload=false , argsargitems.addr="expr" , argsargitems.noupdate=true

這裡有一個例子:

/ declaration of the codelet /

pragma hmpp simple1 codelet, argsoutv.io=inout, target=CUDA

static void matvec (int sn, int sm, loat invsm, float inmsnsm, float *outv){

int i, j;

for (i = 0 ; i

group 指令允許宣告一組 codelets。 指令中定義的引數應用於所有屬於該組的 codelets。

該指令的語法是:

pragma hmpp grp_label> group

, version = ..??

, target = targetname:targetname*?

, cond = “expr”?

3.2 資料傳輸指令可以最佳化通訊開銷

硬體使用時的主要瓶頸通常是硬體和住處理器之間的資料傳輸。

要限制通訊開銷，可以透過使用硬體的非同步屬性，連續執行相同的 codelet 以重疊資料傳輸。

allocate 指令

allocate 指令鎖定硬體，並分配所需的記憶體量。

pragma hmpp grplabel> allocate ,argsargitems.size={dimsize,dimsize*}
release 指令

release 指令指定何時為一組或一個獨立 codelet 釋放硬體。

pragma hmpp grp_label> release
advancedload 指令

advancedload 指令在 codelet 遠端執行之前預取資料。

pragma hmpp grplabel> codeletlabel? advancedload

,argsarg_items

,argsargitems.size={dimsize,dimsize*} ,argsargitems.addr="expr" ,argsargitems.section={subscripttriplet,+} ,asynchronous

delegatedstore 指令

delegatedstore 指令是一個同步障，以等待一個非同步 codelet 執行完成，然後下載結果。

pragma hmpp grplabel> codeletlabel? delegatedstore

,argsarg_items

,argsargitems.addr="expr" ,argsargitems.section={subscript_triplet,+}

非同步計算

同步指令指定等待，直到一個非同步 callsite 執行完成。對於同步指令，codelet 標籤始終是強制性的，並且若是 codelet 屬於一個組，需要有組標籤。

pragma hmpp grplabel> codeletlabel synchronize
示例

在下面的例子中，完成裝置初始化，記憶體分配和輸入資料的上載在迴圈外只有一次，而不是每次迴圈迭代。

同步指令允許在啟動另一個迭代之前等待 codelet 的非同步執行的完成。最後在迴圈外 delegatedstore 指令將上載 sgemm 結果。

int main (int argc, char argv) {* pragma hmpp sgemm allocate, argsvin1;vin2;vout.siez={size,size}
pragma hmpp sgemm advancedload, argsvin1;vin2;vout, argsm,n,k,alpha,beta

for ( j = 0 ; j

所有對映引數的型別和尺寸必須是相同的。

map 指令對映裝置上的幾個引數。

pragma hmpp grplabel> map, argsargitems

此指令除了引數按其名稱直接指定對映之外，與 map 指令很類似。 mapbyname 指令相當於多對映指令。

pragma hmpp grp_label> mapbyname ,variableName+

3.3 全域性變數

Resident 指令宣告某些變數在一個組內為全域性變數。 然後可以從任何屬於組的 codelet 中直接訪問這些變數。此指令應用於原始碼中在其之後的宣告語句。

此指令的語法是:

pragma hmpp grp_label> resident

, args::varname.io=inout , args::varname.size={dimsize,dimsize*} , args::varname.addr="expr" , args::varname.const=true

符號::var_name 以：為字首，表示一個應用程式的變數宣告為 resident。

3.4 加速區

codelet/callsite 指令合併為一個區域。目的是避免程式碼重構中構建 codelet。 因此，所有 codelet 或 callsite 指令可用屬性都可以用於 regions 指令。

在 C 語言中:

pragma hmpp MyGroup> label region

, argsargitems.io=inout , cond = "expr", argsargitems.const=true , target=targetname:targetname , argsargitems.size={dimsize,dimsize*} , argsargitems.advancedload=false , argsargitems.addr="expr" , argsargitems.noupdate=true , asynchronous?

, private=arg_items {C BLOCK STATEMENTS}

實現

HMPP 開放標準基於 HMPP 2.3 版本 (2009 年 5 月，CAPS 公司).

HMPP 基於指令的程式設計模型已經實現如下:

HMPP 工作臺，用於混合計算的 CAPS 企業編譯器
PathScale ENZO 編譯器套件 (支援 NVIDIA GPUs)

此外，HMPP 開放標準用於石油和天然氣，能源，製造業，金融，教育及研究領域的高效能計算，讓開發人員使用大部分多核處理器，同時保留其遺留資源。

參閱

圖形處理器通用計算
平行計算