Vulkan 对于vkQueueSubmit,VkFence在哪些情况下优于vkQueueWaitIdle?
如上所述,vkQueueWaitIdle相当于vkFence。Vulkan 对于vkQueueSubmit,VkFence在哪些情况下优于vkQueueWaitIdle?,vulkan,Vulkan,如上所述,vkQueueWaitIdle相当于vkFence。 所以在哪种情况下可以使用它们中的任何一个。坦率地说,你应该总是选择等待,因为等待更灵活 有了围栏,你可以等待工作完成,而不必等待等待工作完成后提交的工作。围栏还允许其他线程将命令缓冲区推送到队列,而不会干扰等待 除此之外,WaitQueueIdle的实现方式可能与在围栏上等待不同(且效率较低) 正如您所说,vkQueueWaitIdle()只是围栏使用的一个特例 因此,当您需要编写10行等效的Fence代码时,您可以使用它,尤其是当
所以在哪种情况下可以使用它们中的任何一个。坦率地说,你应该总是选择等待,因为等待更灵活 有了围栏,你可以等待工作完成,而不必等待等待工作完成后提交的工作。围栏还允许其他线程将命令缓冲区推送到队列,而不会干扰等待
除此之外,WaitQueueIdle的实现方式可能与在围栏上等待不同(且效率较低) 正如您所说,
vkQueueWaitIdle()
只是围栏使用的一个特例
因此,当您需要编写10行等效的Fence代码时,您可以使用它,尤其是当您不想记住以前提交的所有队列时。这在某种程度上是一种调试功能(通常您会临时使用它来测试同步)。在清理过程中(例如,应用程序终止或重建swapchain),它可能很有用
在所有其他情况下,您应该选择更通用的VkFence
s:
vkWaitForFences()
用法。也就是说,等待一个vs等待全部和超时
vkQueueWaitIdle()
)。您可以执行以下操作:vkQueueSubmit(q,1,si1,fence1)代码>
vkQueueSubmit(q,1,si2,fence2)代码>
vkwaitfeens(fence1);//与vkQueueWaitIdle(q)不同,不会在第二次提交时阻止
甚至可能比:
vkQueueSubmit(q,1,si1,0)代码>
vkQueueWaitIdle(q)代码>
vkQueueSubmit(q,1,si2,0)代码>
vkGetFenceStatus()
查询围栏的状态,而无需等待。例如,有一些背景工作,只是在做其他工作时定期询问是否已经完成VkFence
即使在相同的情况下也可能更快vkQueueWaitIdle()
可以实现为
vkQueueSubmit(q,0,空PTR,围栏);
vkWaitFences(围栏,无限远);
您可能会为vkQueueSubmit
支付额外费用vkQueueWaitIdle
是一种大锤式的同步方法,大致类似于glFlush()
。Vulkan队列是您希望填充的,因为当它为空时,这是一种低效。使用vkQueueWaitIdle
在客户机代码和Vulkan驱动程序部分之间创建一种同步点,这可能导致GPU管道中出现暂停和气泡
栅栏的纹理要细得多。与其要求队列清空所有工作,您只需询问它何时完成围栏之前或使用围栏排队的特定工作集。即使它仍然通过必须将客户机CPU线程与驱动程序CPU线程同步来创建同步点,这仍然使驱动程序可以继续处理队列中的其余项目
信号量甚至比fences更好,因为它们告诉驱动程序一项工作依赖于另一项工作,并让驱动程序完全在内部完成同步,但它们并不适用于所有情况,因为有时客户端需要知道某项工作何时完成