http://blog.csdn.net/bendanban/article/details/7928744
引言:
什么是基于指令的移植方式呢?首先我這里說的移植可以理解為把原先在CPU上跑的程序放到像GPU一樣的協(xié)處理器上跑的這個過程。在英文里可以叫Porting。移植有兩種方式:一種是使用CUDA或者OpenCL來重新設(shè)計代碼,然后使用硬件廠商提供的編譯器來編譯;一種是使用OpenACC或者OpenHMPP提供的指令集添加到你想使用GPU計算的源代碼中的某個位置,讓編譯器來編譯出GPU上執(zhí)行的代碼。后一種方式就是基于指令的移植方式。
例如,下面一個簡單的循環(huán):
for (i=0; i<n;i++)
{
dosomething(i);
}
如果你想把這個循環(huán)放到GPU上,讓每個線程計算一次i的話,可以這樣做:
#pragma acc kernels
for (i=0; i<n;i++)
{
dosomething(i);
}網(wǎng)格化(gridification):
這樣,編譯器拿到加了OpenACC指令的那段代碼后,就會把你的循環(huán)放到GPU或者其他硬件加速器(例如MIC)上。編譯器分析了#pragma acc kernels下面的那個循環(huán),就會根據(jù)循環(huán)的次數(shù)來分配線程數(shù)量,這個過程就叫網(wǎng)格化。為什么說是網(wǎng)格化呢?可以這樣理解,因為GPU可以啟動很多線程,這些線程就像一張漁網(wǎng)一樣,可以認(rèn)為一個網(wǎng)格代表一個線程,所以我就干脆叫這個過程為“網(wǎng)格化”了。
內(nèi)核(kernel)
在OpenACC里可以這樣理解內(nèi)核:內(nèi)核就是在協(xié)處理器(例如GPU)上被多個線程同時執(zhí)行的一段代碼。如果每個線程都做一個活,豈不是沒意思了么?當(dāng)然不是這樣的,他們執(zhí)行的代碼是一樣的,但是每個線程可以根據(jù)自己的ID號來針對不同的數(shù)據(jù)做同樣的工作,這也就是數(shù)據(jù)并行的含義。
codelet
使用CAPS的HMPP Workbench編譯加了OpenACC指導(dǎo)語句的源代碼時,編譯器會告訴你codelet產(chǎn)生了。實際上產(chǎn)生了一個CUDA或者OpenCL的源文件,這個源文件中包含了根據(jù)你的指導(dǎo)語句生成的CUDA或者OpenCL的源代碼。那什么是codelet呢?可以認(rèn)為codelet就是數(shù)據(jù)管理+內(nèi)核。一個codelet要干的事情包括兩部分:申請和管理CPU和協(xié)處理器之間的存儲,還有就是啟動在協(xié)處理上執(zhí)行的代碼。
work-sharing
這個詞可以理解為名詞“共享工作”。如果在協(xié)處理器上的線程們執(zhí)行的工作時work-sharing的,那么每個線程可以根據(jù)自己的ID在不同的數(shù)據(jù)上干了相似的工作。這個詞是在使用OpenACC或者OpenHMPP移植代碼的時候遇到的,它描述的是CPU的串行代碼中的狀態(tài),例如:
for (i=0; i<n; i++)
{
a[i] = i;
}在這段代碼中,a[i]的計算與a[i]之外的a的元素沒有依賴性,所以,每次循環(huán)的i可以使獨立的完成的,像這樣的狀態(tài)就是work-sharing的。還有例如規(guī)約,
s = 0;
for (i=0; i<n; i++)
{
s+=a[i];
}雖然s的計算與i相關(guān),但是細(xì)想一下,加法在數(shù)學(xué)上市滿足交換律的,s的每次加a[i]實際上不相關(guān)的,你不管以什么順序加和a[i]到s,解結(jié)果總是一樣的。所以規(guī)約也可以理解為是worksharing 的。就說這么多吧。如果大家有什么問題,歡迎給我留言奧。



