繁体   English   中英

并发NDKernal启动的OpenCL多命令队列

[英]OpenCL multiple command queue for Concurrent NDKernal Launch

我正在尝试运行矢量加法应用程序,在该应用程序中我需要同时启动多个内核,因此对于并发内核启动,我在最后一个问题中建议有人使用多个命令队列。 我通过数组定义

context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &err);
    for(i=0;i<num_ker;++i)
    {
queue[i] = clCreateCommandQueue(context, device_id, 0, &err);
    }

在上述代码的某些地方,出现错误“命令被信号11终止”。

我也使用for循环来启动内核和入队数据

 for(i=0;i<num_ker;++i)
 {
 err = clEnqueueNDRangeKernel(queue[i], kernel, 1, NULL, &globalSize, &localSize,
                                                          0, NULL, NULL);
 }

问题是我不确定mi哪里出错了,我看到某个地方可以建立命令队列数组,所以这就是为什么我使用数组的原因。 另一个信息,当我不使用A for循环时,只需手动定义多个命令队列,它就可以正常工作。

我也阅读了您的最后一个问题,我认为您应该首先重新考虑您真正想做什么,以及OpenCL是否真的是这样做的方式。

OpenCL是用于大型并行处理和数据处理的API。 每个内核(或排队的任务)同时在多个数据值上并行运行的地方,因此比任何串行CPU处理都要好几个数量级。

OpenCL的典型用例是1个运行数百万个工作项的内核。 如果应用程序更高级,则可能需要多个不同内核的序列,以及CPU和GPU之间的特殊同步。

但是并发并不是必须的。 (否则,单核CPU将无法执行任务,那绝对不是。它会比较慢,可以,但仍然可以运行它)

即使需要同时运行2个任务。 并发时间是否相同:

非并发情况:

Kernel 1: *
Kernel 2: -
GPU Core 1: *****-----
GPU Core 2: *****-----
GPU Core 3: *****-----
GPU Core 4: *****-----

并发情况:

Kernel 1: *
Kernel 2: -
GPU Core 1: **********
GPU Core 2: **********
GPU Core 3: ----------
GPU Core 4: ----------

实际上,非并发情况是优选的,因为至少第一任务已经完成并且进一步的处理可以继续。


据我了解,您想要做的是同时运行多个内核。 这样内核才能完全同时运行。 例如,运行100个内核(相同或不同的内核)并同时运行它们。

这根本不适合OpenCL模型。 而且实际上可能比CPU单线程慢得多。

如果每个内核都独立于其他所有内核,则一次只能为一个内核分配一个内核(SIMD或CPU)(因为它们只有1台PC),即使它们可以同时运行1k线程。 在理想情况下,这会将您的OpenCL设备转换为几个内核(6-10)的池,这些池按顺序消耗排队的内核。 前提是该API也支持它和设备,但情况并非总是如此。 在最坏的情况下,您将拥有运行单个内核的单个设备,并且浪费了99%。

在OpenCL中可以完成的工作示例:

  • 数据处理/处理。 将向量相乘,模拟粒子等。
  • 图像处理,边界检测,过滤等
  • 视频压缩,版本,生成
  • 光线追踪,复杂的光数学等
  • 排序

不适合OpenCL的内容示例:

  • 出席异步请求(HTTP,流量,交互式数据)
  • 处理少量数据
  • 处理每种类型的数据需要完全不同的处理

从我的角度来看,使用多个内核的唯一实际用例是后者,并且无论您做什么,在那种情况下性能都会很糟糕。 最好改用多线程池。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM