加速結(jié)構(gòu)在空間上組織幾何體以加速光線跟蹤遍歷性能。創(chuàng)建加速結(jié)構(gòu)時,會分配保守的內(nèi)存大小。
在初始構(gòu)建時,圖形運行時不知道幾何體如何最佳地適應超大的加速結(jié)構(gòu)內(nèi)存分配。
在 GPU 上執(zhí)行構(gòu)建之后,圖形運行時報告加速結(jié)構(gòu)可以容納的最小內(nèi)存分配。
這個過程稱為壓縮加速結(jié)構(gòu),它對于減少加速結(jié)構(gòu)的內(nèi)存開銷非常重要。
減少記憶的另一個關(guān)鍵因素是對加速結(jié)構(gòu)的子分配。子分配通過使用比圖形 API 所要求的內(nèi)存對齊方式更小的內(nèi)存對齊方式,使加速結(jié)構(gòu)能夠在內(nèi)存中緊密地打包在一起。
通常,緩沖區(qū)分配對齊最小為 64 KB ,而加速結(jié)構(gòu)內(nèi)存對齊要求僅為 256 B 。使用許多小加速結(jié)構(gòu)的游戲從子分配中受益匪淺,使許多小分配能夠緊密打包。
NVIDIA RTX 內(nèi)存實用程序( RTX MU ) SDK 旨在降低與加速結(jié)構(gòu)優(yōu)化內(nèi)存管理相關(guān)的編碼復雜性。 RTX MU 為 DXR 和 Vulkan 光線跟蹤提供壓縮和子分配解決方案,同時客戶端管理加速結(jié)構(gòu)構(gòu)建的同步和執(zhí)行。 SDK 為這兩個 API 提供了子分配器和壓縮管理器的示例實現(xiàn),同時為客戶機實現(xiàn)自己的版本提供了靈活性。
有關(guān)壓縮和子分配在減少加速結(jié)構(gòu)內(nèi)存開銷方面為何如此重要的更多信息,請參見 提示:加速結(jié)構(gòu)壓實 。
為什么使用 RTX MU ?
RTX MU 允許您將加速結(jié)構(gòu)內(nèi)存縮減技術(shù)快速集成到他們的游戲引擎中。下面是這些技術(shù)的總結(jié),以及使用 RTX MU 的一些關(guān)鍵好處
減少加速結(jié)構(gòu)的內(nèi)存占用,包括壓縮和子分配代碼,實現(xiàn)起來并不簡單。 RTX MU 可以完成繁重的工作。
抽象了底層加速結(jié)構(gòu)( blase )的內(nèi)存管理,但也足夠靈活,允許用戶根據(jù)引擎的需要提供自己的實現(xiàn)。
管理壓縮大小回讀和壓縮副本所需的所有屏障。
將句柄傳遞回引用復雜 BLAS 數(shù)據(jù)結(jié)構(gòu)的客戶端。這可以防止對 CPU 內(nèi)存的任何管理不當,包括訪問已經(jīng)釋放或不存在的 BLAS 。
有助于將 BLAS 內(nèi)存減少 50% 。
通過將更多的 BLASE 打包到 64 KB 或 4 MB 頁中,可以減少翻譯查找緩沖區(qū)( TLB )未命中。
RTX MU 設(shè)計
RTX MU 有一種設(shè)計理念,可以降低大多數(shù)開發(fā)人員的集成復雜性。該設(shè)計理念的主要原則如下:
所有函數(shù)都是線程安全的。如果同時訪問發(fā)生,它們將被阻塞。
客戶機傳入客戶機擁有的命令列表, RTX MU 填充它們。
客戶機負責同步命令列表執(zhí)行。
API 函數(shù)調(diào)用
RTX MU 抽象了與壓縮和子分配相關(guān)的編碼復雜性。本節(jié)中詳細介紹的函數(shù)描述了 RTX MU 的接口入口點。
Initialize – 指定子分配程序塊大小。
PopulateBuildCommandList – 接收 D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS 數(shù)組并返回加速結(jié)構(gòu)句柄向量,以便客戶端稍后在頂級加速結(jié)構(gòu)( TLAS )構(gòu)造期間獲取加速結(jié)構(gòu) GPU VAs ,依此類推。
PopulateUAVBarriersCommandList –接收加速度結(jié)構(gòu)輸入并為其放置 UAV 屏障
PopulateCompactionSizeCopiesCommandList –執(zhí)行拷貝以傳遞任何壓縮大小數(shù)據(jù)
PopulateUpdateCommandList – 接收 D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS 數(shù)組和有效的加速結(jié)構(gòu)句柄,以便記錄更新。
PopulateCompactionCommandList – 接收有效的加速結(jié)構(gòu)句柄數(shù)組,并記錄壓縮命令和屏障。
RemoveAccelerationStructures – 接收一個加速結(jié)構(gòu)句柄數(shù)組,該數(shù)組指定可以完全釋放哪個加速結(jié)構(gòu)。
GarbageCollection – 接收一個加速結(jié)構(gòu)句柄數(shù)組,該數(shù)組指定可以釋放生成資源(暫存和結(jié)果緩沖區(qū)內(nèi)存)。
GetAccelStructGPUVA – 接收加速結(jié)構(gòu)句柄并根據(jù)狀態(tài)返回結(jié)果或壓縮緩沖區(qū)的 GPU VA 。
Reset – 釋放與當前加速結(jié)構(gòu)句柄關(guān)聯(lián)的所有內(nèi)存。
子分配程序 DXR 設(shè)計
BLAS 子分配程序通過將小的 BLAS 分配放在較大的內(nèi)存堆中,來滿足 64kb 和 4mb 的緩沖區(qū)對齊要求。 BLAS 子分配程序仍然必須滿足 BLAS 分配所需的 256B 對齊。
如果應用程序請求 4mb 或更大的子分配塊,那么 RTX MU 使用具有堆的已放置資源,這些堆可以提供 4mb 對齊。
如果應用程序請求的子分配塊少于 4MB ,那么 RTX MU 將使用提交的資源,它只提供 64KB 的對齊。
BLAS 子分配程序通過維護空閑列表重用塊中的空閑子分配。如果內(nèi)存請求大于子分配程序塊大小,則會創(chuàng)建一個無法子分配的分配。
壓實 DXR 設(shè)計
如果構(gòu)建請求壓縮,那么 RTX MU 請求將壓縮大小寫入視頻內(nèi)存塊。壓縮大小從視頻內(nèi)存復制到系統(tǒng)內(nèi)存后, RTX MU 分配一個子分配的壓縮緩沖區(qū),用作壓縮復制的目的地。
壓縮拷貝獲取包含未使用的內(nèi)存段的原始構(gòu)建,并將其截短到可以容納的最小內(nèi)存占用。壓縮完成后,原始的非壓縮構(gòu)建和暫存內(nèi)存將釋放回子分配程序。唯一需要擔心的是傳入 allow compression 標志并用 BLAS 句柄調(diào)用 GetGPUVA 。 GPU VA 可以是原始版本,也可以是壓縮版本,這取決于 BLAS 處于什么狀態(tài)。
如何使用 RTX MU
在本節(jié)中,我將詳細介紹 RTX MU 序列循環(huán)和同步。
RTX MU 序列環(huán)路
圖 1 顯示了 RTX MU 的正常使用模式。客戶機管理命令列表的執(zhí)行,而其他一切都是對 RTX MU 的調(diào)用
首先,通過傳入子分配程序塊大小和負責分配子分配塊的設(shè)備來初始化 RTX MU 。在每一幀中,引擎構(gòu)建新的加速結(jié)構(gòu),同時也壓縮先前幀中構(gòu)建的加速結(jié)構(gòu)。
在 RTX MU 填充客戶機的命令列表之后,客戶機就可以自由地執(zhí)行和管理初始構(gòu)建到最終壓縮拷貝構(gòu)建的同步。在調(diào)用 PopulateCompactionCommandList 之前,確保每個加速結(jié)構(gòu)構(gòu)建都已完全執(zhí)行,這一點很重要。這是留給客戶妥善管理。
當加速結(jié)構(gòu)最終達到壓縮狀態(tài)時,客戶機可以選擇調(diào)用 GarbageCollection ,它通知 RTX MU 可以釋放暫存和原始加速結(jié)構(gòu)緩沖區(qū)。如果引擎執(zhí)行大量的資產(chǎn)流,那么客戶端可以通過使用有效的加速結(jié)構(gòu)句柄調(diào)用 RemoveAS 來釋放所有加速結(jié)構(gòu)資源。
圖 1 描述客戶機和 RTX MU 代碼的典型用例的 RTX MU 流程圖
客戶端加速結(jié)構(gòu)生成同步
圖 2 顯示了客戶端正確管理壓縮就緒工作負載所需的同步。這里的示例是一個三幀緩沖循環(huán),其中客戶端最多可以有三個異步幀構(gòu)建在 CPU 上并在 GPU 上執(zhí)行。
若要獲取 CPU 側(cè)可用的壓縮大小,生成 0 必須已在 GPU 上執(zhí)行完畢。在客戶端接收到來自 GPU 的 fence 信號后,客戶端可以調(diào)用 RTX MU 來開始壓縮命令列表記錄。
管理加速結(jié)構(gòu)的壓縮同步的一種有用方法是使用某種類型的鍵/值對數(shù)據(jù)結(jié)構(gòu),它跟蹤 RTX MU 給定的每個加速結(jié)構(gòu)句柄的狀態(tài)。加速度結(jié)構(gòu)的四種基本狀態(tài)可描述如下:
Prebuilt – 生成命令記錄在命令列表中,但尚未在 GPU 上完成執(zhí)行。
Built – 初始構(gòu)建已在 GPU 上執(zhí)行,并準備好執(zhí)行壓縮命令。
Compacted – 壓縮拷貝已經(jīng)在 GPU 上完成,并且準備好讓 GarbageCollection 釋放暫存和初始構(gòu)建緩沖區(qū)。
Released – 客戶端從內(nèi)存中釋放加速結(jié)構(gòu),因為它不再在場景中。此時,與加速結(jié)構(gòu)句柄相關(guān)的所有內(nèi)存都被釋放回操作系統(tǒng)。
圖 2 。客戶機代碼只能在初始加速結(jié)構(gòu)構(gòu)建完成在 GPU 上的執(zhí)行之后啟動壓縮工作負載。
RTX MU 測試場景
RTX MU 使用六個文本場景進行了測試,以提供有關(guān)壓縮和子分配的好處的真實用例數(shù)據(jù)。下面的圖只顯示了一些場景。
RTX MU 積分結(jié)果
在測試場景中, NVIDIA RTX 卡上的壓縮平均減少了 52% 的加速度結(jié)構(gòu)。壓縮記憶降低的標準差為 2 。 8% ,比較穩(wěn)定。
圖 6 。 ZVK3] RTX 3000 系列 GPU s 上壓縮打開與關(guān)閉的比較條形圖
在 NVIDIA 和 AMD-HW 上啟用壓縮時, NVIDIA HW 上的內(nèi)存節(jié)省比 AMD 上的內(nèi)存節(jié)省大得多。在啟用壓縮時, NVIDIA 的加速結(jié)構(gòu)內(nèi)存平均比 AMD 小 3 。 26 倍。在 NVIDIA 上如此巨大的內(nèi)存占用減少的原因是沒有壓縮的 AMD 使用的內(nèi)存是 NVIDIA 的兩倍。壓縮還將 NVIDIA 內(nèi)存平均再減少 50% ,而 AMD 傾向于只減少 75% 的內(nèi)存。
圖 7 。 NVIDIA 3000 系列與 AMD 6000 系列 GPU s 的壓縮比較條形圖
子分配在這里講述了一個稍有不同的故事,其中有許多小加速結(jié)構(gòu)的場景(如零日)受益匪淺。子分配帶來的平均內(nèi)存節(jié)省最終為 123MB ,但標準差在 153MB 時相當大。從這些數(shù)據(jù)中,我們可以斷言子分配高度依賴于場景幾何體,并受益于數(shù)千個小三角形計數(shù)的 BLAS 幾何體。
圖 8 。顯示特定場景子分配節(jié)省內(nèi)存的條形圖
源代碼
NVIDIA 是一個開源的 RTX MU SDK ,以及一個集成 RTX MU 的示例應用程序。在 GitHub 上將 RTX MU 作為一個開源項目進行維護可以幫助開發(fā)人員理解邏輯流程并提供修改底層實現(xiàn)的訪問。 RT Bindless 示例應用程序提供了一個 RTX MU 集成的示例 Vulkan 光線跟蹤和 DXR 后端。
下面是如何構(gòu)建和運行集成 RTX MU 的示例應用程序。您必須擁有以下資源:
Windows 、 Linux 或支持 DXR 或 Vulkan 光線跟蹤的操作系統(tǒng)
克馬克 3.12
C ++ 17
Git
首先,使用以下命令克隆存儲庫:
git clone --recursive https://github.com/NVIDIAGameWorks/donut_examples.git
接下來,打開 CMake 。對于 源代碼在哪里 ,輸入 /donut_examples 文件夾。在 /donut_examples 文件夾中創(chuàng)建生成文件夾。對于 在哪里構(gòu)建二進制文件 ,輸入 new build 文件夾。選擇 cmake 變量 NVRHI \ u ,并將“ RTX MU ”設(shè)置為“開”,選擇“配置”,等待其完成,然后單擊“生成”。
如果要使用 Visual Studio 進行構(gòu)建,請選擇 2019 和 x64 version 。在 visualstudio 中打開 donut_examples.sln 文件并生成整個項目。
在 /Examples/Bindless Ray 跟蹤下找到 rt_bindless 應用程序文件夾,選擇項目上下文(右鍵單擊)菜單,然后選擇 啟動項目 。
默認情況下,無綁定光線跟蹤在 DXR 上運行。要運行 Vulkan 版本,請在項目中添加 -vk 作為命令行參數(shù)。
Summary
RTX MU 結(jié)合了壓縮和子分配技術(shù)來優(yōu)化和減少任何 DXR 或 Vulkan 光線跟蹤應用程序的加速結(jié)構(gòu)的內(nèi)存消耗。數(shù)據(jù)表明,使用 RTX MU 可以顯著減少加速結(jié)構(gòu)的內(nèi)存。這使您可以向光線跟蹤場景添加更多幾何體,或?qū)㈩~外內(nèi)存用于其他資源。
關(guān)于作者
Peter Morley 在 NVIDIA 擔任高級開發(fā)技術(shù)工程師。他的大部分工作集中在將 DXR 集成到 AAA 游戲引擎上。他以前的工作包括在 AMD 的驅(qū)動程序堆棧中實現(xiàn) DXR1.0 和 1.1 。他于 2017 完成了羅德島大學的 MSC ,并幫助使用隱馬爾可夫模型研究體素空間光線跟蹤狀態(tài)估計。當他不玩游戲時,他喜歡和家人一起玩足球。
Jarvis McGee 是 NVIDIA 的高級開發(fā)技術(shù)工程師,致力于各種圖形技術(shù)的集成和優(yōu)化 Vulkan 。 7 年來, Jarvis 一直在游戲行業(yè)內(nèi)優(yōu)化 AAA 游戲的渲染。他為 2K Games 和 Playstation 的各種游戲的發(fā)行做出了貢獻。他完成了在加利福尼亞南部加利福尼亞大學的 MSC ,并協(xié)助在美國南加州大學創(chuàng)新技術(shù)研究所展示數(shù)字人類的研究。在他的閑暇時間,你可以發(fā)現(xiàn)他在舊金山灣地區(qū)嘗試新的渲染技術(shù)和徒步旅行。
審核編輯:郭婷
-
NVIDIA
+關(guān)注
關(guān)注
14文章
4990瀏覽量
103119 -
API
+關(guān)注
關(guān)注
2文章
1502瀏覽量
62080
發(fā)布評論請先 登錄
相關(guān)推薦
評論