Share via


居住

當 GPU 可存取物件時,物件會被視為 常駐 物件。

落地預算

GPU 尚不支援頁面錯誤,因此應用程式必須在 GPU 可以存取數據時,將數據認可到物理記憶體中。 此程式稱為「進行常駐專案」,必須同時針對實體系統記憶體和實體離散視訊記憶體執行。 在 D3D12 中,大部分的 API 物件會封裝一些 GPU 可存取的記憶體。 該 GPU 可存取的記憶體會在建立 API 對象期間進行常駐,並在 API 物件解構時收回。

進程可用的物理記憶體數量稱為視訊記憶體預算。 隨著背景進程喚醒和睡眠,預算可能會明顯波動:當使用者切換到另一個應用程式時,和會大幅波動。 當預算變更並輪詢目前預算和目前耗用的記憶體數量時,應用程式可以收到通知。 如果應用程式未維持在其預算內,程式將會間歇性凍結,以允許其他應用程式執行和/或建立 API 將傳回失敗。 IDXGIAdapter3 介面提供與這項功能相關的方法,特別是 QueryVideoMemoryInfo RegisterVideoMemoryBudgetChangeNotificationEvent。

鼓勵應用程式使用保留來表示其不需使用的記憶體數量。 在理想情況下,使用者指定的「低」圖形設定,或更低的圖形設定,是這類保留的正確值。 設定保留永遠不會為應用程式提供比通常收到的更高的預算。 相反地,保留資訊可協助OS核心快速將大型記憶體壓力情況的影響降到最低。 即使保留項目不保證在應用程式不是前景應用程式時可供應用程式使用。

堆積資源

雖然許多 API 物件會封裝一些 GPU 可存取的記憶體,但堆積和資源應該是應用程式取用和管理物理記憶體的最重要方式。 堆積是管理物理記憶體的最低層級單位,因此最好熟悉其落地屬性。

  • 堆積無法部分常駐,但保留的資源存在因應措施。
  • 堆積應作為特定集區的一部分進行預算。 UMA 配接器有一個集區,而離散配接器則有兩個集區。 雖然核心可以將離散適配卡上的一些堆積從視訊記憶體轉移到系統記憶體,但它只會做為極端的最後手段。 應用程式不應該依賴核心的預算過高行為,而應該改為專注於良好的預算管理。
  • 堆積可以從落地收回,以允許將其內容分頁到磁碟。 但是,破壞堆積是一種更可靠的技術,可釋放所有配接器架構之間的落地。 在D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT的MaxGPUVirtualAddressBitsPerProcess 欄位接近預算大小的適配卡上,Evict 將無法可靠地回收落地。
  • 堆積建立可能會很慢;但它已針對背景線程處理進行優化。 建議您在背景線程上建立堆積,以避免發生轉譯線程問題。 在 D3D12 中,多個線程可以安全地呼叫建立例程。

D3D12 為其資源模型引進了更大的彈性和正交性,以便為應用程式啟用更多選項。 D3D12 中有三種高階資源類型:已認可、放置和保留。

  • 認可資源同時建立資源與堆積。 堆積是隱含的,無法直接存取。 堆積的大小適當,以找出堆積內的整個資源。
  • 放置的資源允許在堆積內的非零位移放置資源。 位移通常必須對齊 64KB;但有一些例外狀況存在於兩個方向。 MSAA 資源需要 4MB 位移對齊,而 4KB 位移對齊適用於小型紋理。 放置的資源無法直接重新配置或重新對應至另一個堆積;但是,它們可讓您在堆積之間簡單重新配置資源數據。 在不同的堆積中建立新的放置資源並複製資源數據之後,新的資源描述元必須用於新的資源數據位置。
  • 只有在配接器支援磚化資源第1層或更新版本時,才能使用保留的資源。 當可用時,他們會提供最先進的落地管理技術;但並非所有配接器目前都支持它們。 它們可讓您重新對應資源,而不需要重新產生資源描述元、部分 Mip 層級落地,以及疏鬆紋理案例等。並非所有的資源類型都支援,即使有保留的資源可供使用,因此完全一般頁面型落地管理員尚不可行。

落地優先順序

Windows 10 Creators Update 可讓開發人員在記憶體壓力要求降級部分資源時,影響偏好保留哪些堆積和資源。 這可協助開發人員利用運行時間無法從 API 使用方式推斷的知識,來建立更好的執行應用程式。 其預期開發人員會更舒適且能夠指定優先順序,因為它們會從使用認可的資源轉換到重新配置和並排顯示的資源。

套用這些優先順序必須比管理兩個易失記憶體預算更容易,手動降級和提升資源,因為應用程式已經可以這麼做。 因此,落地優先順序 API 的設計當然會以合理的預設優先順序,依其建立方式指派給每個堆積或資源。 如需詳細資訊,請參閱 ID3D12Device1::SetResidencyPriorityD3D12_RESIDENCY_PRIORITY 列舉。

優先使用優先順序時,開發人員應該會:

  • 提高少數特殊堆積的優先順序,以更好地減輕這些堆積比其自然存取模式更快速或更頻繁地降級的經歷效能影響。 從 Direct3D 11 或 OpenGL 等圖形 API 移植的應用程式應該會利用這種方法,其資源管理模型明顯不同於 Direct3D 12。
  • 根據程式設計人員對存取頻率或動態的知識,使用應用程式本身的貯體化配置,覆寫幾乎所有堆積優先順序;固定配置比動態配置更容易管理,但效率較低,而且因為開發過程中的使用模式變更而需要程式設計人員的內建。 此方法預計將由使用 Direct3D 12 樣式的資源管理所建置的應用程式運用,例如使用落地連結庫的應用程式(尤其是動態配置)。

默認優先順序演算法

應用程式無法指定它嘗試管理之任何堆積的實用優先順序,而不需要先實例化預設優先順序演算法。 這是因為將特定優先順序指派給堆積的值衍生自其相對優先順序至競爭相同記憶體的其他優先順序堆積。

選擇用來產生預設優先順序的策略是將堆積分類為兩個貯體,有利於(優先處理)假設由 GPU 針對不是堆積的堆積經常寫入的堆積。

高優先順序貯體包含堆積和資源,這些資源會以旗標建立,這些旗標會將它們識別為轉譯目標、深度樣板緩衝區或未排序的存取檢視 (UAV)。 這些會指派D3D12_RESIDENCY_PRIORITY_HIGH範圍中的優先順序值;為了在這些堆積和資源之間進一步排定優先順序,優先順序的最低 16 位會設定為堆積大小或資源除以 10MB 的大小(飽和至極大型堆積的0xFFFF)。 這個額外的優先順序有利於較大的堆積和資源。

低優先順序貯體包含所有其他堆積和資源,這些堆積和資源會獲指派D3D12_RESIDENCY_PRIORITY_NORMAL的優先順序值。 不會嘗試這些堆積和資源之間的進一步優先順序。

程序設計落地管理

簡單應用程式可能只建立認可的資源,直到發生記憶體不足失敗為止。 失敗時,應用程式可以終結其他認可的資源或 API 物件,讓進一步的資源建立成功。 但是,即使是簡單的應用程式,也強烈建議您監看負面預算變更,並大約一次框架終結未使用的 API 物件。

嘗試優化配接器架構或納入落地優先順序時,落地管理設計的複雜性將會上升。 離散預算和管理兩個離散記憶體集區會比只管理一個集區更複雜,而且如果使用模式演進,將固定優先順序指派到更廣泛的優先順序可能會成為維護負擔。 將紋理溢位至系統記憶體會增加更複雜的程度,因為系統記憶體中的錯誤資源可能會嚴重影響幀速率。 此外,沒有簡單的功能可協助識別可受益於較高 GPU 頻寬或容許較低 GPU 頻寬的資源。

更複雜的設計會查詢目前配接器的功能。 此資訊可在D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORTD3D12_FEATURE_DATA_ARCHITECTURE、D3D12_TILED_RESOURCES_TIERD3D12_RESOURCE_HEAP_TIER中使用。

應用程式的多個部分可能會使用不同的技術來結束。 例如,某些大型紋理和很少練習的程式代碼路徑可能會使用認可的資源,而許多紋理可以使用串流屬性來指定,並使用一般放置的資源技術。

ID3D12Heap

記憶體管理