【问题标题】:Using different OpenCL command queues from multiple host threads使用来自多个主机线程的不同 OpenCL 命令队列
【发布时间】:2017-06-09 15:00:45
【问题描述】:

相同的 OpenCL 程序在不同的 OpenCL 设备上编译,可能在不同的平台上。为每个设备创建一个命令队列。例如,可能有两个队列,一个用于 CPU,一个用于 GPU。

是否可以从不同的主机线程(每个命令队列一个)在两个命令队列上调用clEnqueueNDRangeKernel 然后clEnqueueReadBuffer(阻塞)?

例如使用 OpenMP,循环类似

// queues_ contains command queues for different contexts,
// each with one device on one platform (e.g. CPU and GPU)
#pragma omp parallel for num_threads(2) schedule(dynamic)
for(int i = 0; i < job_count; ++i) {
    cl::CommandQueue& queue = queues_[omp_get_thread_num()];
    // queue is for one device on one platform
    // euqueue kernel, and read buffer on queue
}

这会将作业列表分为 CPU 和 GPU 两块。 schedule(dynamic) 将使调度动态适应内核的执行时间。 主机代码将花费大部分时间等待内核(在阻塞的clEnqueueReadBuffer 调用中。)但是由于 CPU 设备,CPU 实际上会忙于执行内核(在 OpenCL 中),同时等待GPU 完成(在主机代码中)。

【问题讨论】:

  • 对于你的问题,答案是肯定的。
  • 我创建了一个实时光线追踪器,用于平衡两个 GPUS 和 CPU 之间的负载。我通过为每个具有自己上下文的设备创建一个线程来做到这一点。我为此使用了 pthreads(因为当时我不了解 OpenMP),但我认为 OpenMP 也可以正常工作。我创建了一个单独的上下文,因为当时我没有使用 Nvidia GPU (OpenCL 1.1) 获得单独的队列,并且在 Nvidia 论坛中,Nvidia 的某个人建议为每个设备创建一个不同的上下文,每个设备都有自己的线程。

标签: c++ multithreading opencl openmp scheduling


【解决方案1】:

如果上下文也不同,那么它们会独立工作,即使是 3D 应用程序也是如此。根据实现,两个上下文可以被驱动程序抢占或超线程,但您可以进一步在上下文之间添加基于事件的同步,以便队列 a 中的一个项目等待队列 b 中的项目完成。

如果它们位于相同的上下文中,您可以使用驱动程序或 api 高性能操作在两个队列之间进行隐式同步。

为内存绑定内核使用所有 cpu 内核并不能让它足够快地在 gpu 之间进行数组复制,除非您使用直接内存访问复制时设置 cpu 没有复制指令。如果缓存足够大且足够快,也许它不需要这样的东西。

【讨论】:

    猜你喜欢
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-05
    • 2017-08-30
    • 2017-08-07
    • 1970-01-01
    相关资源
    最近更新 更多