OpenCL内核是否异步执行?

芬利

对于CUDA,我知道它们是在将启动命令发布到默认流(空流)后异步执行的,那么在OpenCL中呢?示例代码如下:

cl_context context;
cl_device_id device_id;
cl_int err;
...
cl_kernel kernel1;
cl_kernel kernel2;
cl_command_queue Q = clCreateCommandQueue(context, device_id, 0, &err);
...
size_t global_w_offset[3] = {0,0,0};
size_t global_w_size[3] = {16,16,1};
size_t local_w_size[3] = {16,16,1};
err = clEnqueueNDRangeKernel(Q, kernel1, 3, global_w_offset, global_w_size, 
                             local_w_size, 0, nullptr, nullptr);
err = clEnqueueNDRangeKernel(Q, kernel2, 3, global_w_offset, global_w_size, 
                             local_w_size, 0, nullptr, nullptr);
clFinish(Q);

命令排队后是否kernel1kernel2异步执行?(即执行重叠)

更新
按照OpenCL的参考,这似乎是一套propertiesCL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLEclCreateCommandQueue能满足我的需要。但是,out_of_order是否意味着异步?

瓦卡尔

在您当前的代码中:

err = clEnqueueNDRangeKernel(Q, kernel1, 3, global_w_offset, global_w_size, 
                             local_w_size, 0, nullptr, nullptr);
err = clEnqueueNDRangeKernel(Q, kernel2, 3, global_w_offset, global_w_size, 
                             local_w_size, 0, nullptr, nullptr);

kernel1先完成然后kernel2执行

使用


clCreateCommandQueue(context, device_id, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &err);

即使没有保证,您也可以同时执行多个不同的内核。

但是请注意,CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE并非所有OpenCL实施都支持。这也意味着您无法保证kernel1将在之前完成执行kernel2如果kernel1需要通过输出的任何对象作为中的输入kernel2,则可能会失败。

还可以创建多个命令队列并将其与命令排队,其存在的原因是因为您要解决的问题可能涉及主机中的某些(即使不是全部)异构设备。它们可以表示没有共享数据的独立计算流,也可以表示每个后续任务都依赖于前一个任务(通常是数据共享)的依赖计算流。但是,只要不共享数据,这些命令队列将在设备上执行而不会同步。如果数据是共享的,则程序员需要使用OpenCL规范中的同步命令来确保数据同步。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章