OpenCL 1.1规范说:
cl_int clEnqueueBarrier(cl_command_queue command_queue)
clEnqueueBarrier是一个同步点,可确保command_queue中的所有排队命令在下一批命令开始执行之前已完成执行.
cl_int clFinish(cl_command_queue command_queue)
阻止将所有先前在command_queue中排队的OpenCL命令发送到关联设备并完成.在处理完成command_queue中的所有排队命令之前,clFinish不会返回.clFinish也是一个同步点.
应该对有序或无序执行做些什么,但我看不出差别.如果我有顺序执行,他们是否需要?目前我做的事情如下:
...
for(...){
clEnqueuNDRangeKernel(...);
clFlush(command_queue);
clFinish(command_queue);
}
...
Run Code Online (Sandbox Code Playgroud)
在Nvidia GPU上.任何相关评论表示赞赏.
如果您正在编写无序队列作为确保依赖性的一种方法,则需要将障碍排入队列.您还可以使用这些cl_event对象来确保命令队列上的命令的正确排序.
如果您正在编写代码,以便clFinish在每次内核调用之后调用,那么使用clEnqueueBarrier将不会对代码产生任何影响,因为您已经确保了订购.
使用的点将是clEnqueueBarrier如下情况:
clEnqueueNDRangeKernel(queue, kernel1);
clEnqueueBarrier(queue);
clEnqueueNDRangeKernel(queue, kernel2);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,kernel2取决于kernel1的结果.如果此队列是乱序的,那么没有障碍,kernel2 可以在kernel1之前执行,从而导致不正确的行为.您可以通过以下方式实现相同的排序
clEnqueueNDRangeKernel(queue, kernel1);
clFinish(queue);
clEnqueueNDRangeKernel(queue, kernel2);
Run Code Online (Sandbox Code Playgroud)
因为clFinish会等到队列为空(所有内核/数据传输都已完成).但是,clFinish等到kernel1完成后,在这种情况下,clEnqueueBarrier应该立即将控制权返回给应用程序(允许您将更多内核排入队列或执行其他有用的工作.
作为旁注,我认为这clFinish将隐式调用,clFlush所以你不应该每次都调用它.