名詞的概念:
1涛救、cl_int clGetPlatformIDs (cl_uint num_entries,cl_platform_id *platforms,cl_uint *num_platforms)
Platform (平臺(tái)):主機(jī)加上OpenCL框架管理下的若干設(shè)備構(gòu)成了這個(gè)平臺(tái)匆光,通過(guò)這個(gè)平臺(tái),應(yīng)用程序可以與設(shè)備共享資源并在設(shè)備上執(zhí)行kernel鞭达。實(shí)際使用中基本上一個(gè)廠商對(duì)應(yīng)一個(gè)Platform,比如Intel, AMD都是這樣。
2、cl clGetDeviceIDs (cl_platform_id platform,cl_device_type device_type,cl_uint num_entries,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cl_device_id *devices,cl_uint *num_devices)
Device(設(shè)備):官方的解釋是計(jì)算單元(Compute Units)的集合沫换。舉例來(lái)說(shuō),GPU是典型的device轧叽。Intel和AMD的多核CPU也提供OpenCL接口苗沧,所以也可以作為Device刊棕。
3炭晒、cl_context clCreateContext (const cl_context_properties *properties,?cl_uint num_devices,
const cl_device_id *devices,
void ( CL_CALLBACK *pfn_notify)(const char *errinfo,const void *private_info, size_t cb,void *user_data),
void *user_data,cl_int *errcode_ret)
Context(上下文):OpenCL的Platform上共享和使用資源的環(huán)境待逞,包括kernel、device网严、memory objects识樱、command queue等。使用中一般一個(gè)Platform對(duì)應(yīng)一個(gè)Context震束。
4怜庸、cl_command_queue clCreateCommandQueue (cl_context context,cl_device_id device,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?cl_command_queue_properties properties,cl_int *errcode_ret)
當(dāng)設(shè)備執(zhí)行任務(wù)時(shí),由主機(jī)來(lái)提交命令垢村,將命令發(fā)送到隊(duì)列中割疾。命令隊(duì)列和設(shè)備對(duì)應(yīng),一個(gè)命令隊(duì)列只能關(guān)聯(lián)到一個(gè)設(shè)備嘉栓,但是單個(gè)設(shè)備可以有多個(gè)命令隊(duì)列宏榕,這就可以將不同的命令提交到不同隊(duì)列。
Command Queue(指令隊(duì)列):在指定設(shè)備上管理多個(gè)指令(Command)侵佃。隊(duì)列里指令執(zhí)行可以順序也可以亂序麻昼。一個(gè)設(shè)備可以對(duì)應(yīng)多個(gè)指令隊(duì)列。
5馋辈、cl_program?clCreateProgramWithSource (cl_context context,cl_uint count,const char **strings,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const size_t *lengths,cl_int *errcode_ret)
cl_int?clBuildProgram (cl_program program,cl_uint num_devices,const cl_device_id *device_list,
const char *options,
void ( CL_CALLBACK *pfn_notify)(cl_program program,void *user_data),
void *user_data)
Program:OpenCL程序抚芦,由kernel函數(shù)、其他函數(shù)和聲明等組成迈螟。
6叉抡、cl_mem clCreateBuffer (cl_context context,cl_mem_flags flags,size_t size,void *host_ptr,
cl_int *errcode_ret)
Memory Object(內(nèi)存對(duì)象):在主機(jī)和設(shè)備之間傳遞數(shù)據(jù)的對(duì)象,一般映射到OpenCL程序中的global memory答毫。有兩種具體的類(lèi)型:Buffer Object(緩存對(duì)象)和Image Object(圖像對(duì)象)卜壕。
cl_int clEnqueueReadBuffer (cl_command_queue command_queue,cl_mem buffer,cl_bool blocking_read,
size_t offset,size_t size,void *ptr,cl_uint num_events_in_wait_list,const cl_event *event_wait_list,
cl_event *event)
7、cl_kernel?clCreateKernel (cl_program program,?const char *kernel_name,?cl_int *errcode_ret)
Kernel(核函數(shù)):可以從主機(jī)端調(diào)用烙常,運(yùn)行在設(shè)備端的函數(shù)轴捎。
cl_int clSetKernelArg (cl_kernel kernel,cl_uint arg_index,size_t arg_size,const void *arg_value)
8、cl_int?clEnqueueNDRangeKernel (cl_command_queue command_queue,cl_kernel kernel,
cl_uint work_dim,const size_t *global_work_offset,const size_t *global_work_size,
const size_t *local_work_size,cl_uint num_events_in_wait_list,const cl_event *event_wait_list,
cl_event *event)
NDRange:主機(jī)端運(yùn)行設(shè)備端kernel函數(shù)的主要接口蚕脏。實(shí)際上還有其他的侦副,NDRange是非常常見(jiàn)的,用于分組運(yùn)算驼鞭,以后具體用到的時(shí)候就知道區(qū)別了秦驯。
9. 設(shè)置Group Size
一個(gè)OpenCL運(yùn)行任務(wù)中并行計(jì)算的單位是work-item。而work-item的組織形式就由維數(shù)(dim),各維度尺寸( global_work_size)和分組方式( local_work_size)等參數(shù)決定挣棕。
注意幾點(diǎn):一是維數(shù)译隘,一般的OpenCL設(shè)備最大支持維數(shù)為3亲桥,可以查詢CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS來(lái)獲取固耘;二是local_work_size题篷,合適的size與具體OpenCL設(shè)備的最大并發(fā)資源有關(guān),可以不設(shè)置厅目。
/** step 9: set work group size */
cl_uint work_dim = 3;
// in most opencl device, max dimition is 3
size_t global_work_size[] = { ARRAY_SIZE, 1, 1 };
size_t *local_work_size = NULL; // let opencl device determine how to break work items into work groups
Host端來(lái)看番枚,OpenCL的組要執(zhí)行流程是這樣的:
List basic kernel source:
char *kernelSource =
"__kernel void test(__global int *pInOut)\n"
"{\n"
" int index = get_global_id(0);\n"
" pInOut[index] += pInOut[index];\n"
"}\n";
與這個(gè)例子運(yùn)算結(jié)果等價(jià)的程序?yàn)?br>
for (int i = 0; i < ARRAY_SIZE; i++)
{
a[i] += a[i];
}