Opencl clEnqueueBarrier和clFinish有什么区别?
OpenCL 1.1规范规定: CLU int CLENQUEUEBARIER(CLU命令队列命令队列) clEnqueueBarrier是一个同步点,用于确保在下一批命令开始执行之前,命令队列中的所有排队命令都已完成执行 cl_int clFinish(cl_命令队列命令队列) 阻塞,直到命令队列中所有先前排队的OpenCL命令被发送到相关设备并完成。clFinish在命令队列中的所有排队命令都已处理并完成之前不会返回。clFinish也是一个同步点 应该对有序执行或无序执行做些什么,但我看不出有什么区别。如果我有命令执行,是否需要它们?目前,我做了如下工作:Opencl clEnqueueBarrier和clFinish有什么区别?,opencl,gpu,Opencl,Gpu,OpenCL 1.1规范规定: CLU int CLENQUEUEBARIER(CLU命令队列命令队列) clEnqueueBarrier是一个同步点,用于确保在下一批命令开始执行之前,命令队列中的所有排队命令都已完成执行 cl_int clFinish(cl_命令队列命令队列) 阻塞,直到命令队列中所有先前排队的OpenCL命令被发送到相关设备并完成。clFinish在命令队列中的所有排队命令都已处理并完成之前不会返回。clFinish也是一个同步点 应该对有序执行或无序执行做些什么,但我看不
...
for(...){
clEnqueuNDRangeKernel(...);
clFlush(command_queue);
clFinish(command_queue);
}
...
在Nvidia GPU上。如有任何相关评论,我们将不胜感激 如果要将无序队列作为确保依赖性的一种方法写入,则需要将屏障排队。您还可以使用
cl\u事件
对象来确保命令队列上的命令顺序正确
如果编写代码时在每次内核调用后调用clFinish
,那么使用clEnqueueBarrier
不会对代码产生任何影响,因为您已经在确保排序
使用clEnqueueBarrier
的要点如下:
clEnqueueNDRangeKernel(queue, kernel1);
clEnqueueBarrier(queue);
clEnqueueNDRangeKernel(queue, kernel2);
在这种情况下,kernel2取决于kernel1的结果。如果此队列出现故障,那么在没有障碍的情况下,kernel2可能在kernel1之前执行,从而导致错误行为。您可以通过以下方式实现相同的订购:
clEnqueueNDRangeKernel(queue, kernel1);
clFinish(queue);
clEnqueueNDRangeKernel(queue, kernel2);
因为clFinish
将等待队列为空(所有内核/数据传输都已完成)。但是,clFinish
将等待内核1完成,在这种情况下,clEnqueueBarrier
应立即将控制权返回给应用程序(允许您将更多内核排队或执行其他有用的工作)
作为旁注,我认为
clFinish
将隐式调用clFlush
,因此您不必每次都调用它。谢谢您的回答。因此,总结一下:两者都是这样做的,但是clEnqueueBarrier()是一个异步函数,因此它会立即继续承载代码。我测试了两个解决方案,如果一个比另一个需要更多的时间,但似乎没有这样的问题。我想知道clEnqueueBarrier是否实际上等同于clEnqueueMarker,然后是clEnqueueWaitForEvents?或者是否有一些我忽略的细节?@TomiAarnio这可能是clEnqueueBarrier的一个实现,但我不确定clEnqueueMarker在无序队列中是如何工作的,这可能会影响这两个队列的语义。对于有序队列,我认为可能是这样。