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