【发布时间】: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