如何通過(guò) PCIe 總線(xiàn)優(yōu)化從 CPU 到 GPU 的 DX12 資源上傳是一個(gè)老問(wèn)題,有許多可能的解決方案,每個(gè)解決方案都有其優(yōu)缺點(diǎn)。在這篇文章中,我將展示如何使用 NVAPI 將 DX12 上傳堆移動(dòng)到 CPU-Visible VRAM ( CVV ),這是一個(gè)加速 PCIe 有限工作負(fù)載的簡(jiǎn)單解決方案。
CPU-Visible VRAM :工具箱中的新工具
以頂點(diǎn)緩沖區(qū)( VB )上載為例,數(shù)據(jù)不能跨幀重用。將 VB 上載到 GPU 的最簡(jiǎn)單方法是直接從 GPU 讀取 CPU 內(nèi)存:
首先,應(yīng)用程序創(chuàng)建 DX12 UPLOAD 堆或等效的 CUSTOM 堆。 DX12 上傳堆分配在系統(tǒng)內(nèi)存中,也稱(chēng)為 CPU 內(nèi)存,其中 WRITE_COMBINE ( WC )頁(yè)面針對(duì) CPU 寫(xiě)入進(jìn)行了優(yōu)化。 CPU 首先將 VB 數(shù)據(jù)寫(xiě)入此系統(tǒng)內(nèi)存堆。
其次,應(yīng)用程序使用 IASetVertexBuffers 命令將上載堆中的 VB 綁定到 GPU draw 命令。
在 GPU 中執(zhí)行繪制時(shí),將啟動(dòng)頂點(diǎn)著色器。接下來(lái),頂點(diǎn)屬性提取( VAF )單元通過(guò) GPU 的二級(jí)緩存讀取 VB 數(shù)據(jù),二級(jí)緩存本身從存儲(chǔ)在系統(tǒng)內(nèi)存中的 DX12 上載堆加載 VB 數(shù)據(jù):
圖 1 直接從 DX12 上傳堆獲取 VB 。
來(lái)自系統(tǒng)內(nèi)存的 L2 訪(fǎng)問(wèn)具有高延遲,因此最好在執(zhí)行 draw 命令之前通過(guò)將數(shù)據(jù)從系統(tǒng)內(nèi)存復(fù)制到 VRAM 來(lái)隱藏該延遲。
從 CPU 到 GPU 的預(yù)上載可以通過(guò)使用 copy 命令來(lái)完成,可以使用 COPY 隊(duì)列異步完成,也可以在主直接隊(duì)列上同步完成。
圖 2 使用 copy 命令將 VB 預(yù)加載到 VRAM
復(fù)制引擎可以在復(fù)制隊(duì)列中與其他 GPU 工作同時(shí)執(zhí)行復(fù)制命令,并且可以同時(shí)使用多個(gè)復(fù)制隊(duì)列。但是,使用異步復(fù)制隊(duì)列的一個(gè)問(wèn)題是,您必須注意將隊(duì)列與 DX12 Fences 同步,這可能很難實(shí)現(xiàn),并且可能會(huì)有很大的開(kāi)銷(xiāo)。
在 GTC 2021 的 Nsight Graphics : GPU Trace 的下一級(jí)優(yōu)化建議 會(huì)議上,我們宣布 NVIDIA GPU 上 DX12 應(yīng)用程序的替代解決方案是有效地使用 CPU 線(xiàn)程作為復(fù)制引擎。這可以通過(guò)使用 NVAPI 在 CVV 中創(chuàng)建 DX12 上載堆來(lái)實(shí)現(xiàn)。 CPU 然后通過(guò) PCIe 總線(xiàn)將寫(xiě)入此特殊上載堆的數(shù)據(jù)直接轉(zhuǎn)發(fā)到 VRAM (圖 3 )。
圖 3 在 CPU 線(xiàn)程中使用 CPU 寫(xiě)操作將 VB 預(yù)加載到 VRAM
對(duì)于 DX12 ,以下 NVAPI 函數(shù)可用于查詢(xún)系統(tǒng)中可用的 CVV 量,并用于分配這種新風(fēng)格的堆( CPU – 可寫(xiě) VRAM ,具有快速 CPU 寫(xiě)入和慢速 CPU 讀取):
NvAPI_D3D12_QueryCpuVisibleVidmem
NvAPI_D3D12_CreateCommittedResource
NvAPI_D3D12_CreateHeap2
這些新功能需要最新的驅(qū)動(dòng)程序: 466 。 11 或更高版本。
NvAPI_D3D12_QueryCpuVisibleVidmem 應(yīng)報(bào)告以下 CVV 內(nèi)存量:
使用 Windows 11 (例如,使用 Windows11 內(nèi)幕預(yù)覽 )時(shí) NVIDIA RTX 20xx 和 30xx GPU s 的容量為 200-256 MB 。
可調(diào)整大小的條_ RTX 30xx GPU s 在 Windows 10 或 Windows 11 中超過(guò) 256 MB ,且 NVIDIA 控制面板中的 可調(diào)整大小的條_ 報(bào)告為 NVIDIA 。有關(guān)如何啟用可調(diào)整大小欄的更多信息,請(qǐng)參閱 GeForce RTX 30 系列通過(guò)可調(diào)整大小的桿支撐加速性能 。
使用 Nsight Graphics 從 CPU-Visible VRAM 檢測(cè)并量化 GPU 性能增益機(jī)會(huì)
NVIDIA NSight 圖形 2021 。 3 中的 GPU 跟蹤工具可輕松檢測(cè) GPU 性能提升機(jī)會(huì)。啟用 高級(jí)模式 時(shí), GPU 內(nèi)的 Analysis 面板將根據(jù)預(yù)測(cè)的幀減少百分比,通過(guò)修復(fù)此 GPU 工作負(fù)載中的特定問(wèn)題,跟蹤幀內(nèi)的顏色代碼 perf 標(biāo)記。
以下是在 RTX NVIDIA 3080 上,從 看門(mén)狗:軍團(tuán) ( DX12 )預(yù)發(fā)布版本中選擇 Analyze 后的幀的外觀:
圖 4 帶有顏色編碼 GPU 工作負(fù)載的 GPU 跟蹤分析工具
(越綠,幀上的預(yù)計(jì)增益越高)。
現(xiàn)在,選擇幀末尾的用戶(hù)界面繪制命令,分析工具顯示,修復(fù) 二級(jí)未命中到系統(tǒng)內(nèi)存 性能問(wèn)題后 GPU 幀時(shí)間預(yù)計(jì)減少 0 。 9% 。該工具還顯示,通過(guò)二級(jí)緩存?zhèn)鬏數(shù)拇蠖鄶?shù)系統(tǒng)內(nèi)存流量是由基本引擎請(qǐng)求的,該引擎包括頂點(diǎn)屬性獲取單元:
圖 5 GPU 跟蹤分析工具,關(guān)注單個(gè)工作負(fù)載。
通過(guò)在 CVV 中分配此 draw 命令的 VB ,而不是使用常規(guī) DX12 上載堆分配系統(tǒng)內(nèi)存,此機(jī)制的 GPU 時(shí)間從 0.2 ms 減少到 0.01 ms 以下。 GPU 幀時(shí)間也減少了 0.9% 。在此工作負(fù)載中, VB 數(shù)據(jù)現(xiàn)在直接從 VRAM 獲取:
圖 6 GPU 跟蹤分析工具,在優(yōu)化了工作負(fù)載之后。
使用 Nsight 系統(tǒng)避免 CPU 讀取 CPU – 可見(jiàn) VRAM
CPU 不應(yīng)讀取常規(guī) DX12 上載堆,而應(yīng)僅將其寫(xiě)入。與常規(guī)堆一樣, CVV 堆的 CPU 內(nèi)存頁(yè)已啟用 寫(xiě)合并 。這提供了快速的 CPU 寫(xiě)入性能,但緩慢的非緩存 CPU 讀取性能。此外,由于從 CVV 讀取 CPU 會(huì)通過(guò) PCIe 、 GPU L2 和 VRAM 進(jìn)行往返,因此從 CVV 讀取的延遲遠(yuǎn)大于從常規(guī) DX12 上載堆讀取的延遲。
要檢測(cè)應(yīng)用程序 CPU 的性能是否受到來(lái)自 CVV 的 CPU 讀取的負(fù)面影響,并獲取 CPU 調(diào)用導(dǎo)致這種情況的信息,我建議使用 Nsight 系統(tǒng) 2021.3 。
示例 1 : CVV CPU 讀取 ReadFromSubresource
下面是一個(gè)在 Nsight 系統(tǒng)跟蹤中從 DX12 ReadFromSubresource 讀取災(zāi)難性 CPU 的示例。為了捕獲此跟蹤,在獲取跟蹤時(shí),我在 Nsight 系統(tǒng)項(xiàng)目配置中啟用了新的 收集 GPU 指標(biāo) 選項(xiàng),以及默認(rèn)設(shè)置,其中包括 樣本目標(biāo)過(guò)程 。
以下是 Nsight Systems 在放大一個(gè)代表性幀后顯示的內(nèi)容:
圖 7 Nsight 系統(tǒng)顯示 2 。 6 ms ReadFromSubresource 調(diào)用與來(lái)自 BAR1 的高 PCIe 讀取請(qǐng)求計(jì)數(shù)相關(guān)的 CPU 線(xiàn)程。
在這種情況下(單個(gè) – GPU 機(jī)器), Nsight Systems 中的 對(duì) BAR1 的 PCIe 讀取請(qǐng)求 GPU 指標(biāo)測(cè)量發(fā)送到 PCIe 的 CPU 讀取請(qǐng)求數(shù),以獲取 CVV ( BAR1 )中分配的資源。 Nsight Systems 顯示 CPU 線(xiàn)程上的長(zhǎng) DX12 ReadFromSubresource 調(diào)用與來(lái)自 CVV 的大量 PCIe 讀取請(qǐng)求之間存在明顯的相關(guān)性。因此,您可以得出結(jié)論,此調(diào)用很可能是從 CVV 執(zhí)行 CPU 回讀,并在應(yīng)用程序中修復(fù)此問(wèn)題。
示例 2 : CVV CPU 從映射指針讀取
CPU 從 CVV 讀取的數(shù)據(jù)不限于 DX12 命令。當(dāng)使用 DX12 資源映射調(diào)用返回的任何 CPU 內(nèi)存指針時(shí),它們可能發(fā)生在任何 CPU 線(xiàn)程中。這就是為什么建議使用 Nsight 系統(tǒng)對(duì)其進(jìn)行調(diào)試,因?yàn)槌诉x定的 GPU 硬件指標(biāo)外, Nsight 系統(tǒng)還可以定期對(duì)每個(gè) CPU 線(xiàn)程的調(diào)用堆棧進(jìn)行采樣。
以下是 Nsight 系統(tǒng)的一個(gè)示例,其中顯示了從 CVV 進(jìn)行的 CPU 讀取與沒(méi)有 DX12 API 調(diào)用相關(guān),但與 CPU 線(xiàn)程活動(dòng)開(kāi)始相關(guān):
圖 8 Nsight Systems 顯示了執(zhí)行映射調(diào)用的 CPU 線(xiàn)程與對(duì) BAR1 的 PCIe 讀取請(qǐng)求之間的相關(guān)性,之后該相關(guān)性立即增加。
通過(guò)懸停在 CPU 線(xiàn)程下面的橙色采樣點(diǎn),您可以看到該線(xiàn)程正在執(zhí)行一個(gè)名為 RenderCollectedTrees 的 C ++方法,這對(duì)查找正在進(jìn)行 CVV 堆讀/寫(xiě)操作的代碼是有幫助的:
圖 9 Nsight Systems 顯示 CPU 線(xiàn)程的調(diào)用堆棧采樣點(diǎn),該線(xiàn)程與對(duì) BAR1 的高 PCIe 讀取請(qǐng)求相關(guān)。
在這種情況下,提高性能的一種方法是對(duì) CPU 內(nèi)存的單獨(dú)塊執(zhí)行讀/寫(xiě)訪(fǎng)問(wèn),而不是在 DX12 上載堆中。完成所有讀/寫(xiě)更新后,從 CPU 讀/寫(xiě)內(nèi)存向上載堆執(zhí)行 memcpy 調(diào)用。
結(jié)論
在 Windows 11 PC 上運(yùn)行的所有 PC 游戲都可以在 NVIDIA RTX 20xx 和 30xx GPU s 上使用 256 MB 的 CVV 。 NVAPI 可用于查詢(xún)系統(tǒng)中可用 CVV 內(nèi)存的總量,并在此空間中分配 DX12 內(nèi)存。如果 CPU 從未從原始 DX12 上載堆讀取數(shù)據(jù),則只需更改分配堆的代碼即可將 DX12 上載堆替換為 CVV 堆。
要檢測(cè)將 DX12 上載堆移動(dòng)到 CVV 時(shí) Nsight 圖形 的性能提升機(jī)會(huì),建議使用 GPU 中的 GPU 跟蹤分析工具。要檢測(cè)和調(diào)試從 CVV 讀取 CPU 時(shí)的性能損失,我建議在啟用 GPU 指標(biāo)的情況下使用 Nsight 系統(tǒng) 。
關(guān)于作者
Louis Bavoil 自 2007 年以來(lái)一直在 NVIDIA 的開(kāi)發(fā)者技術(shù)小組工作,從事 GPU 性能優(yōu)化和 GameWorks 軟件開(kāi)發(fā)的混合工作,目標(biāo)是幫助提高 PC 游戲的生產(chǎn)價(jià)值。
審核編輯:郭婷
-
NVIDIA
+關(guān)注
關(guān)注
14文章
5238瀏覽量
105730 -
gpu
+關(guān)注
關(guān)注
28文章
4908瀏覽量
130622 -
WINDOWS
+關(guān)注
關(guān)注
4文章
3606瀏覽量
90903
發(fā)布評(píng)論請(qǐng)先 登錄
HarmonyOS優(yōu)化應(yīng)用預(yù)置圖片資源加載耗時(shí)問(wèn)題性能優(yōu)化
提升AI訓(xùn)練性能:GPU資源優(yōu)化的12個(gè)實(shí)戰(zhàn)技巧

可以手動(dòng)構(gòu)建imx-gpu-viv嗎?
DLP4500燒錄,同樣格式的圖片(8bit),上傳到第Index16時(shí)總是報(bào)錯(cuò),為什么?
GPU按需計(jì)費(fèi)的優(yōu)勢(shì)
GPU加速云服務(wù)器怎么用的
英特爾12月或發(fā)布Battlemage GPU芯片
怎么把電表監(jiān)測(cè)到的數(shù)據(jù)上傳平臺(tái)?

評(píng)論