2016-09-18 64 views
1

在vulkan.h的VkAccessFlagBits每個實例出現在包含srcAccessMask一對和dstAccessMask爲什麼VkAccessFlagBits包含讀取位和寫入位?

VkAccessFlags  srcAccessMask; 
VkAccessFlags  dstAccessMask; 

在每一種情況下,根據我的理解,這些面具的目的是爲了幫助指定兩套的操作,從而第一組中的操作結果將對第二組中的操作可見。例如,在屏障之前發生的寫操作不應該掛在緩存中,而應該一直傳播到屏障之後可以讀取它們的位置。或類似的東西。

訪問標誌進來讀寫形式:

/* ... */ 
VK_ACCESS_SHADER_READ_BIT = 0x00000020, 
VK_ACCESS_SHADER_WRITE_BIT = 0x00000040, 
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 0x00000080, 
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100, 
/* ... */ 

但在我看來,srcAccessMask應該總有某種VK_ACCESS_*_WRITE_BIT組合,而dstAccessMask應始終VK_ACCESS_*_READ_BIT值的組合。如果這是真的,那麼READ/WRITE區別與src/dst區別是相同的並且是隱含的,所以它應該足夠好以便具有VK_ACCESS_SHADER_BIT等,沒有READ_或WRITE_變體。

爲什麼會有READ_和WRITE_變種呢?指定某些讀取操作在一些其他操作開始之前必須完全完成是否有用?請注意,所有使用VkAccessFlagBits的操作都會產生(我認爲)執行依賴性以及內存依賴性。在我看來,執行依賴關係應該足夠好,以防止較早的讀取接收稍後寫入的值。

回答

2

在寫這個問題我遇到以提供一個答案的至少一部分的規格福爾康一個語句:

存儲器依賴性用於解決數據的危害,例如確保寫入操作對後續讀取操作(寫入後讀取危險)可見,以及寫入後寫入危險。寫後讀和後讀後讀危險只需要執行依賴關係來進行同步。

這是從部分6.4。執行和內存依賴。此外,從早些時候在該節:

應用程序必須使用內存的依賴,使寫入可見之前的後續讀取可以依靠他們,並且之前的後續寫入可以覆蓋它們。不這樣做會導致讀取結果未定義,並且寫入的順序未定義。

由此我推測,是的,這涉及這些訪問標誌的福爾康命令產生的執行依賴性可能做免費的,你甚至不必把一個VK_ACCESS_*_READ_BITsrcAccessMask場 - 但是,你可能會在事實上想要在dstAccessMask的某些字段中使用READ_標誌,WRITE_標誌或兩者,因爲顯然可以使用顯式依賴性來防止寫後寫入危險,從而避免寫入後寫入危險。 (也許反之亦然?)

比如,也許你的Vulkan有時會決定寫一個實際上並不需要通過一個特定的緩存傳播到它的最終指定的目的地,以便後續的讀操作,如果Vulkan碰巧知道讀取操作將簡單地從相同的緩存讀取,節省一些時間?但是可能會發生第二次寫入,並寫入不同的緩存,並且在比賽中會有兩個緩存(選擇未定義的贏家)將它們的兩個值發送到同一個地方。或者其他的東西?也許我對這些緩存的心理模型是完全錯誤的。

至少,這是相當牢固的建立,至少,記憶障礙混亂。

+0

無論如何,如果有人不同於我,實際上知道這些緩存或其他什麼在某些真實硬件上工作,都想要解釋如何讓Vulkan知道一個屏障是讀寫屏障而另一個屏障是寫入屏障,寫障礙 - 就像爲什麼,詳細地說,它不僅僅是以同樣的方式處理? (或者我真的得到了那個權利??) - 那麼我會很高興。但一個普通的Vulkan用戶prolly並不需要知道我認爲 – mjwach

+0

我確定這不是關於HW本身。如果有的話,這對駕駛員如何處理事情會有些微妙的影響。 – krOoze

+0

硬件線程調度可能包括基於寫地址的分片。分片將共享高速緩存,從而避免不使用高速緩存刷新的寫後寫操作(它只需要執行順序同步)。我不知道是否有任何硬件實際上實現了這種類型的分片。但Vulkan規範旨在將完全控制權應用於需要非常詳細的操作描述的應用程序,以同等支持所有類型的可能硬件。 –

1

讓我們去了一切準備:

  • 閱讀–閱讀—好耶是一個很沒用的。 Khronos似乎同意#131這是src(基本相當於0)毫無意義的價值。

  • 讀–寫—執行依賴關係應該足以在沒有這種情況下進行同步。 Khronos似乎同意#131這是src(基本相當於0)毫無意義的價值。

  • 寫–讀—這是最明顯和最常見的一個。

  • 寫–寫—類似的原因寫–以上閱讀。沒有它,寫入的順序將是不確定的。在大多數情況下寫一些你甚至沒有閱讀過的東西是沒有意義的。但是,嘿,現在你有辦法同步它。

您可以將更多這些掩碼的位掩碼提供給src和dst。在這種情況下,讓驅動程序爲您分配依賴關係的掩碼是有意義的。 (我不希望API級別的性能開銷,因此可以方便)

從API設計角度來看,它可能意味着爲srcAccess添加不同的枚舉。但可能_READ變體只能通過「有效用法」在srcAccess中被禁止,從而使這個論證變得虛弱。 src == READ變種可能已被保留,因爲它是良性的。

+0

這似乎與我的粗略聲明(在我的答案中)中的READ_BIT標誌永遠不需要在srcAccessMask中設置相沖突。你認爲這種說法是不正確的? – mjwach

+0

@mjwach:這不就是你的問題嗎?你的解釋是否正確? –

+0

@krOoze:僅執行依賴關係將確保「讀取 - >寫入」問題。內存依賴(這些就是這些)關於寫作。 –

相關問題