OpenCL 创建命令队列

在OpenCL上下文中,有内存、程序和内核对象,对这些对象的操作就需要使用命令队列。一条命令就是主机发送给设备的一条消息,用来告诉设备执行一个操作。这个操作包含主机与设备间、设备内的数据拷贝与内核执行。命令提交到命令队列中,命令队列把需要执行的命令发送给设备。需要注意的是,每条命令队列只能关联一个设备,如果要同时使用多个设备,则需要创建多个命令队列,每个命令队列关联到一个设备,如下图所示。

发送命令到设备

命令队列中的命令,只能是主机发送给设备,而设备不能发送命令给主机。默认情况下,命令队列顺序处理接收到的命令,但是在创建命令队列时可以修改默认行为。

clCreateCommandQueueWithProperties

虽然旧版本OpenCL标准中的clCreateCommandQueue函数也可以给命令队列指定特性,但是真正可用的只有CL_QUEUE_PEROPERTIES,对于乱序执行绝大多数设备并不支持。在OpenCL 2.0中对该函数进行了扩展,扩展后的函数如下:

cl_command_queue clCreateCommandQueueWithProperties(
                                    cl_context context,
                                    cl_device_id device,
                                    const cl_queue_properties *properties,
                                    cl_int *errcode_ret)

函数返回cl_command_queue,除了第三个参数properties,其他参数都是比较容易理解的。对于第三个参数properties,指定了命令队列的属性,及其相应的值的列表。每个属性名称后面紧跟对应的值。列表以0结尾。properties属性名称及其描述如下表所示:

cl_queue_property值列表

设置CL_QUEUE_PROFILING_ENABLE,可以接收命令队列处理命令的时间事件,通过这个开发人员可以分析程序性能参数。

默认情况下,命令队列里的命令遵循先进先出(FIFO)原则,设置CL_QUEUE_OUT_OF_OERDER_EXEC_MODE_ENABLE,设备将乱序执行内核,如设备将会在前一个内核执行命令完成之前执行其他内核。对于数据有前后依赖系的两个内核来说,这就需要同步。可以使用事件来实现同步。

在OpenCL 2.0中,允许设备向命令队列提交命令,这个过程不需要主机参与。这样的命令队列,需要设置为CL_QUEUE_ON_DEVICE|CL_QUEUE_ON_DEVICE_DEFAULT。

如下代码展示了如何使用cl_queue_properties属性值来创建命令队列:

cl_queue_properties props[]=
{
};
    CL_QUEUE_PROPERTIES, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
    | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT,
    0
clCreateCommandQueueWithProperties(context, device, props, &err);

clGetCommandQueueInfo

对于创建的命令队列,可以通过下列函数查询命令队列各个属性信息:

cl_int clGetCommandQueueInfo(cl_command_queue command_queue,
                                  cl_command_queue_info parame_name,
                                  size_t param_value_size,
                                  void *param_value,
                                  size_t *param_value_size_ret)

参数param_name为查询属性名称,取值见下表,参数param_value返回命令队列查询属性信息。

命令队列属性查询

可以使用如下函数来改变命令队列引用计数的值:

cl_int clRetainCommandQueue(cl_command_queue command_queue)
cl_int clReleaseCommandQueue(cl_command_queue command_queue)

clRetainCommandQueue增加命令队列引用计数(引用计数+1)。
clReleaseCommandQueue减少命令队列引用计数(引用计数-1)。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程