OpenCL的 clFinish()
API调用阻塞,直到命令队列上的所有命令都完成执行。一个相关的功能。clFlush()
,据说
在命令队列中向与命令队列相关联的设备发出所有之前排队的OpenCL命令。
这是什么意思?是不是让这些命令跳过对事件的等待?这听起来并不合理。它是否会阻塞,直到命令被发出?可能不是,这就是 clFinish()
确实如此。这几乎看起来就像 clFlush()
其实不必做任何事情。
我错过了什么?
当你enqueue 异步 命令,但并不能保证GPU真的会执行这些命令。
这些异步命令通常是内存传输(clEnqueueWriteBuffer,clEnqueueReadBuffer),阻塞标志设置为CL_FALSE,以及内核调用(clEnqueueNDRangeKernel)。
如果你想保证命令会执行,你必须enqueue***等阻塞命令,阻塞标志设置为CL_TRUE,或者调用clFinish。
clFlush也保证了你enqueue的命令会被执行。这些命令会被 "刷新 "到硬件命令缓冲区,并在GPU调度器调度它们时被执行。
这背后的逻辑是,最有效的方法是用最大的工作量让GPU饱和(通过许多enqueue调用填满一个大的命令缓冲区),然后用一个同步调用(clFinish)或clFlush告诉GPU执行所有的命令。
你可能想调用clFlush而不是clFinish的原因是,如果你希望 叠加 CPU工作与GPU工作。
clEnqueue*** // async
clEnqueue*** // async
clEnqueue*** // async
clFlush(...); // async, make sure commands will execute
// do some heavy CPU work while GPU is executing commands
clFinish(...); // synchronous, ensure all commands are done, collect results.