使用来自多个主机线程的不同OpenCL命令队列

时间:2017-01-24 17:24:41

标签: c++ multithreading opencl openmp scheduling

相同的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完成(在主机代码中)。

1 个答案:

答案 0 :(得分:1)

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

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

使用cpu的所有内核作为内存绑定内核并不允许它以足够快的速度对gpu进行数组复制,除非你使用直接内存访问当复制时设置cpu没有复制指令。如果缓存很大且足够快,也许它不需要这样的东西。

相关问题