OpenCL执行内核wrile将数据复制到CPU

时间:2018-04-20 21:15:05

标签: opencl gpu gpu-programming

我正在学习OpenCL,我听说有可能在GPU上进行计算并立即复制数据。我喜欢这样:

queue.enqueueNDRangeKernel(ker, cl::NullRange, cl::NDRange(1024*1024));
queue.enqueueReadBuffer(buff, true, 0, 1024*1024, &buffer[0]);

我能够以某种方式立即执行操作吗?在执行具有更高索引的内核时将第一个结果复制回CPU?

我想做点什么:

for(int i=0; i<1024; ++i){
    queue.enqueueNDRangeKernel(ker, cl::Range(i*1024), cl::NDRange(1024));
    queue.enqueueReadBuffer(buff, true, i*1024, 1024, &buffer[i*1024]);
}

但是要异步执行内核和读取。这样的事情可能吗?两个队列和内核完成事件是否正确解决?

感谢您的时间。

2 个答案:

答案 0 :(得分:1)

是的,使用单独的命令队列进行上传,计算和下载(以及要同步的事件!)是重复复制和计算的正确方法。在一些专业级硬件上,你甚至可以重叠上传和下载,因为它们有两个DMA引擎。

答案 1 :(得分:1)

如果您阅读the spec,您会发现自己可以回答自己的问题。特别是,看看&#39; cl_event&#39;几个OpenCL函数的参数。

另外,如果你仔细查看自己的代码,你会看到你将阻止参数设置为true(如果你想阻止它,那么它应该是CL_TRUE,尽管可能就是这样#39} ; s由队列对象处理?)。您将要更改它并使用事件,并在获取事件和在事件列表中使用事件之间使用必要的clFlush()

最后,假设您每次都使用新数据多次执行内核,您可以排队多个内核实例,但这需要在设备的内存中保存更多数据,因此您可能需要小心你不要用完记忆。

编辑:如果要排队多个实例,则需要使用CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE或多个命令队列(甚至两者)。我发现前者更容易使用适当的事件使用,但它实际上归结为个人偏好。