转载 https://deepinout.com/opencl/opencl-basic-tutorials/opencl-create-command-queue.html
在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_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)。