2016-09-16 240 views

回答

2

非常坦率地說,你應該總是更喜歡等待圍欄,因爲它更靈活。

用籬笆,您可以等待工作完成,而無需等待您等待工作後提交的工作。圍欄還允許其他線程將命令緩衝區推送到隊列中,而不會干擾等待。

除了WaitQueueIdle可以以不同的方式實現(效率較低)與等待圍欄相比。

4

正如你所說,vkQueueWaitIdle()只是柵欄使用的特例。
因此,如果您不得不編寫10行等效的Fence代碼,則可以使用它。

VkFence更一般。

  1. 您可以利用先進的vkWaitForFences()用法。即等待一個和等待所有和timeout

  2. 您將它提供給一些應該發信號的命令(不能用vkQueueWaitIdle()來實現)。你可以這樣做:
    vkQueueSubmit(q, 1, si1, fence1);
    vkQueueSubmit(q, 1, si2, fence2);
    vkWaitFences(fence1); // won't block on the 2nd submit unlike vkQueueWaitIdle(q)
    甚至可能是潛在的速度比:
    vkQueueSubmit(q, 1, si1, 0);
    vkQueueWaitIdle(q);
    vkQueueSubmit(q, 1, si2, 0);

  3. 您可以直接查詢圍欄的狀態,而無需等待與vkGetFenceStatus()(其本身似乎是更簡單版本的vkQueueWaitIdle())。例如。有一些背景工作,只是定期詢問在做其他工作時是否已完成。

1

在什麼情況下是VkFence比vkQueueWaitIdle爲vkQueueSubmit更好?

當你關閉福爾康情況下,即在幾乎所有情況。 vkQueueWaitIdle是大錘的同步方法,大致類似於glFlush()。 Vulkan隊列是你想要保持填充,因爲當它是空的時,這是一種低效率。使用vkQueueWaitIdle會在客戶端代碼和Vulkan驅動程序的各個部分之間創建一種同步點,這可能會導致GPU管道中的停頓和泡影。

圍欄更加細膩。與其要求隊列中沒有任何工作,只是詢問何時完成了在圍欄之前或使用圍欄排隊的特定工作集。即使它仍然通過必須將客戶機CPU線程與驅動程序CPU線程同步來創建同步點,這仍然使驅動程序可以自由地繼續處理隊列中的其餘項。

信號比柵欄更好,因爲它們告訴驅動程序一件作品依賴於另一件作品,並讓驅動程序完全在內部完成同步,但它們不適用於所有情況,因爲有時客戶端需要來了解何時完成某項工作。

相關問題