200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > OpenCL异构并行计算编程笔记(1):平台 设备与上下文

OpenCL异构并行计算编程笔记(1):平台 设备与上下文

时间:2020-06-06 13:55:43

相关推荐

OpenCL异构并行计算编程笔记(1):平台 设备与上下文

OpenCL(全称Open Computing Language,开放运算语言)是第一个面向异构系统通用目的并行编程的开放式、免费标准,也是一个统一的编程环境,便于软件开发人员为高性能计算服务器、桌面计算系统、手持设备编写高效轻便的代码,而且广泛适用于多核心处理器(CPU)、图形处理器(GPU)、Cell类型架构以及数字信号处理器(DSP)等其他并行处理器[1]。

需要注意的是,不同于其他第三方库,OpenCL只提供一个开放API的规范,仅仅定义了接口,但并没有进行实现,各个接口的实现由处理器生产厂商自己完成。所以,虽然包括Intel、AMD以及Nvidia在内的厂商都对OpenCL提供了支持,但其实现的方法却各有不同,使得在不用品牌的处理器上使用OpenCL时需要使用特定的SDK,同时在特性上会略微有所不同(但基本不会产生太大影响)。接下来就简单介绍一下基于OpenCL的异构编程方法,在进行OpenCL编程之前,最好先了解OpenCL的架构模型,具体资料可参考:从零开始学习OpenCL开发架构,在此不予赘述。(实例环境:Windows10、Visual Studio 、OpenCL 1.1、Intel Core i5 3437U、Nvidia GeForce 840M)

一、获取平台(Platform):

不同厂商对于OpenCL具体的实现不同,某个厂商对于OpenCL的实现就形成了一个平台。不同厂商的处理器只能在不同的平台上运行,换句话说一个平台上只用运行实现该平台厂商的处理器。例如Intel、AMD和Nvidia均对OpenCL进行了自己的实现,在Intel的平台上可以同时使用Intel的CPU和GPU,但无法使用AMD和Nvidia的处理器;同样在AMD的平台上无法使用Intel和Nvidia二者的设备。在进行OpenCL编程时需要首先确定所选择的平台。

查询平台ID可以使用:

clGetPlatFormIDs(cl_uint num_entries, cl_platform_id*platforms, cl_uint *num_platforms)

该函数的第一个参数是platforms可以保存的平台ID的数目;

第二个参数是一个指针,用来保存找到的平台;

第三个参数保存查询到的平台的个数。

当返回值为0时,标志程序执行完成;非0时,为错误码。

通常可以使用两次该函数来获取所有的平台ID:

[cpp]view plaincopy cl_intret;//用于保存函数返回值cl_uintnum_platform;//用于保存平台个数cl_platform_id*platform//用于保存平台ID////获取函数个数ret=clGetPlatformIDs(NULL,NULL,&num_platform);////为platform分配空间platform=newcl_platform_id[num_platform];//获取所有平台ret=clGetPlatformIDs(num_platform,platform,NULL);

查询平台信息可以使用:

cl_int clGetDeviceIDs(cl_platform_id platform,

cl_platform_info param_name,

size_t param_value_size,

void *param_value,

size_t *param_value_size_ret)

该函数的第一个参数是之前获取的平台ID;

第二个参数是一个枚举体,用来标识所要查询的信息;

第三个参数是一个指针,用来存放查询到的信息;

第四个参数表示指针所指内存的大小;

第五个参数用来存放查询到的信息数据的大小。

同样,通常使用两次该函数来获取平台信息:

[cpp]view plaincopy cl_intret;//用于保存函数返回值size_text_size;//用于保存平台信息大小char*ext_data;//用于保存平台信息cl_platform_infoplatform_info=CL_PLATFORM_NAME;//设置所要查询的信息////获取平台信息大小ret=clGetPlatformInfo(platform[order],platform_info,0,NULL,&ext_size);////为ext_data分配空间ext_data=newchar[ext_size];//获取平台信息ret=clGetPlatformInfo(platform[order],platform_info,ext_size,ext_data,NULL);//打印平台信息std::cout<<ext_data<<std::endl;

二、获取设备(Device):

设备是运行在平台上的可进行异构计算的单元,通常对应于同一平台的处理器。获取设备ID和信息的方法与函数同获取平台类似:

cl_int clGetDeviceIDs(cl_platform_id platform,

cl_device_type device_type,

cl_uint num_entries,

cl_device_id *devices,

cl_uint *num_devices)

第一个参数标识所要查询的平台,第二个参数用来保存查询到设备的类型,其余三个参数的含义与clGetPlatformIDs一致。

cl_int clGetDeviceInfo(cl_device_id device,

cl_device_info param_name,

size_t param_value_size,

void *param_value,

size_t *param_value_size_ret)

第一个参数标识所要查询设备,其余参数的含义与clGetPlatformInfo一致。

设备查询函数的使用和平台一样,一般通过两次调用来获得设备的个数和相应的信息,具体可以参考获取平台相关函数的使用方法。

三、建立上下文(Context):

上下文(Context)是将同一平台上不同架构的设备连接在一起的纽带,在同一个上下文的设备才可以进行通信、读写、共享内存等操作。程序运行时,使用上下文来管理命令队列、内存、内核等对象。建立上下文可以使用:

cl_context clCreateContext(cl_context_properties *properties,

cl_uint num_devices,

const cl_device_id *devices,

void *pfn_notify (const char *errinfo, const void *private_info, size_t cb, void *user_data),

void *user_data,

cl_int *errcode_ret)

该函数第一个参数指向一个列表,用来表明建立的上下文的属性及相对应的值;

第二个参数表明上下文中设备的个数;

第三个参数是指向设备ID的指针,用来标明建立上下文的设备;

第四个参数是一个回调函数,报告建立上下文中出现的错误;

第五个参数用来返回错误码,当上下文建立成功时返回0,即CL_SUCCESS。

如果建立上下文完成,该函数返回一个非0的上下文。

实际使用时根据之前获得的设备ID来建立上下文:

[cpp]view plaincopy cl_intret;//用于保存函数返回值cl_context_propertiescontext_props[]={CL_CONTEXT_PLATFORM,(cl_context_properties)platform[1],0};;//设置上下文属性////建立上下文cl_contextcontext=clCreateContext(context_props,num_device,devices,NULL,NULL,&ret);

建立完上下文,就可以在其后进行建立命令队列、设置内核等操作。我们的OpenCL编程的万里长征也算是完成了第一步。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。