Opencl clFlush(与clFinish相反)实际上做了什么吗?

Opencl clFlush(与clFinish相反)实际上做了什么吗?,opencl,Opencl,OpenCLclFinish()API调用将阻塞,直到命令队列上的所有命令都已完成执行。据推测,这是一个相关的函数 向与命令队列关联的设备发出命令队列中以前排队的所有OpenCL命令 这是什么意思?它是否使这些命令跳过等待事件?这听起来不合理。在发出命令之前它是否会阻塞?可能不是,这就是clFinish()所做的。似乎clFlush()实际上不需要做任何事情 我遗漏了什么?当您使用opencl将异步命令排队时,无法真正保证GPU将实际执行这些命令 这些异步命令通常是内存传输(clEnqueueW

OpenCL
clFinish()
API调用将阻塞,直到命令队列上的所有命令都已完成执行。据推测,这是一个相关的函数

向与命令队列关联的设备发出命令队列中以前排队的所有OpenCL命令

这是什么意思?它是否使这些命令跳过等待事件?这听起来不合理。在发出命令之前它是否会阻塞?可能不是,这就是
clFinish()
所做的。似乎
clFlush()
实际上不需要做任何事情


我遗漏了什么?

当您使用opencl将异步命令排队时,无法真正保证GPU将实际执行这些命令

这些异步命令通常是内存传输(clEnqueueWriteBuffer、clenqueueredbuffer),阻塞标志设置为CL_FALSE和内核调用(clenqueueendrangekernel)

如果您希望保证命令将被执行,则必须将阻塞命令(如阻塞标志设置为CL_TRUE的一个enqueue***命令)排入队列,或调用clFinish

clFlush还保证将执行您排队的命令。命令被“刷新”到硬件命令缓冲区,并在GPU调度程序安排执行时执行

这背后的逻辑是,用最大工作量使GPU饱和(通过许多排队调用填充大的命令缓冲区),然后告诉GPU使用单个同步调用(clFinish)或clFlush执行所有操作,这是最有效的

您可能希望调用clFlush over 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.

在主机端排队执行大量内核调用可能会消耗大量RAM
clFlush
可用于立即向设备提交当前队列。请参阅。@doqtor:但如果这次提交是可能的,为什么还没有发生呢?i、 e.不向设备提交队列命令并等待有什么好处?此外,如果有人将数万或数十万个内核排队,那么我100%确定他们使用OpenCL是错误的(比如链接上的OP应该使用一个内核对一个副本进行所有扫描,或者使用一个内核对所有副本进行一次扫描)。与
clFinish
不同,
clFlush
是异步的,也就是说,当GPU在计算某些东西时,你可以立即获得控制权,同时做其他事情。@doqtor:我知道这是异步的,我只是不明白为什么clFlush可以做的任何事情在被调用之前都不应该发生。
clFlush
/
clFinish
开始执行
clEnqueueNDRangeKernel
,它是惰性的(只添加到队列中)
clFlush
以非阻塞方式执行。因此,从“软件缓冲区”移动到“硬件缓冲区”。但是-无论如何,这不是自动发生的吗?例如,在CUDA中-没有这样的“刷新”操作。另外,如果硬件“命令缓冲区”“不够大,那么clFlush甚至不能保证它应该保证的东西。或者-可能会阻塞?具体行为取决于实现。建议您自己使用codexl/nsight等工具对此进行检查。根据我的经验,clflush甚至对单个内核都有影响。我不记得cuda是否具有此功能,但其他API(如directx和opengl)当然具有此功能。@einpoklum请查看此处的备注部分。想法是一样的。该链接描述的内容听起来更像
clFinish()