弄清楚如何在個人電腦上降低渲染應(yīng)用程序的GPU幀時間可能是一項具有挑戰(zhàn)性的任務(wù),即使是最有經(jīng)驗的PC游戲開發(fā)人員也是如此。本博客文章描述了我們在NVIDIA內(nèi)部使用的性能分類方法,使用NVIDIA特定的硬件度量標(biāo)準(zhǔn)來找出任何給定GPU工作負(fù)載(也稱為性能標(biāo)記或調(diào)用范圍)的主要性能限制器。
我們的性能分類方法并非從假設(shè)或有關(guān)在GPU上呈現(xiàn)的內(nèi)容的知識開始。相反,它僅從硬件指標(biāo)開始,讓我們知道整個GPU的利用情況,哪些硬件單元和子單元限制了性能,以及它們運行到各自的峰值性能的接近程度(也稱為“速度光“或”SOL“)。如果應(yīng)用程序不使用異步計算,則可以將此以硬件為中心的信息映射回圖形API和著色器正在執(zhí)行的操作,從而為如何提高任何給定工作負(fù)載的GPU性能提供指導(dǎo):
-
如果沒有GPU單元具有較高的吞吐量(與SOL相比),那么我們會努力提高至少一個單元的吞吐量。
-
如果一些GPU單元具有較高的吞吐量(與SOL相比),那么我們將弄清楚如何從該單元中刪除工作。
Nsight Range Profiler
從開普勒架構(gòu)1(完全支持Maxwell,Pascal和VoltaGPU)開始,所有NVIDIA GPU上的DX11,DX12和OpenGL上的PerfWorks庫可以捕獲每個GPU工作負(fù)載的硬件指標(biāo)。雖然PerfWorks頭文件尚未公開,但該庫現(xiàn)在可以通過公共工具使用:Nsight的Range Profiler:用于DX12,DX11和OpenGL 4.6(但不包括Vulkan)的Visual Studio Edition 5.5,以及Microsoft的“PIX在Windows上“用于DX12。
1從維基百科上可以看到,GeForce 600和700系列大多是開普勒,900系列是麥克斯韋,1000系列是帕斯卡,而TITAN V是沃爾塔。
第1步:鎖定GPU核心時鐘
首先,為了獲得最具確定性的測量結(jié)果,我們建議您在收集任何性能指標(biāo)之前始終鎖定您的GPU核心時鐘頻率(并在解鎖之后進行解鎖,以獲得最佳性能,以及在GPU空閑或只是最小化功耗和噪聲時做桌面渲染)。在啟用了“開發(fā)者模式”的Windows 10上,可以通過運行一個簡單的DX12應(yīng)用程序來完成此操作,該應(yīng)用程序在虛擬DX12設(shè)備上調(diào)用SetStablePowerState(TRUE),然后在不釋放設(shè)備的情況下進入睡眠狀態(tài),如本博文所述。
注意:從Nsight:Visual Studio版本5.5開始,Range Profiler現(xiàn)在可以在分析任何Range之前/之后有效地調(diào)用SetStablePowerState(),使用適用于所有Windows版本(不僅僅是Windows 10)的內(nèi)部驅(qū)動程序API,也不需要操作系統(tǒng)將處于“開發(fā)者模式”。因此,在使用Nsight Range Profiler時,您不必?fù)?dān)心鎖定GPU Core時鐘。
第2步:用Nsight HUD捕捉畫面
對于非UWP(通用Windows平臺)應(yīng)用程序,這可以通過將您的EXE(或批處理文件)拖放到Nsight安裝在桌面上的“NVIDIA Nsight HUD啟動器”快捷方式來完成,并達到您想要的游戲位置捕捉,然后:
-
按CTRL-Z在屏幕的右上部分顯示Nsight HUD,并
-
點擊Nsight HUD中的“暫停和捕捉幀”按鈕,或者按空格鍵開始捕捉。
您可以通過單擊“將捕獲保存到磁盤”按鈕將當(dāng)前幀導(dǎo)出到Visual Studio C ++項目。(默認(rèn)情況下,Nsight導(dǎo)出的幀被保存到C: Users ... Documents NVIDIA Nsight Captures ...)
你可以點擊“恢復(fù)”繼續(xù)玩你的游戲,以便找到你想要捕捉更多幀的其他位置。
注意:您可以跳過“將捕獲保存到磁盤”步驟并直接跳到下一步(Scrubber&Range Profiler分析),但我們建議始終將捕獲保存到磁盤,并將它們存檔,以便可以返回到它們你需要稍后。將導(dǎo)出的幀保存到磁盤可讓您稍后將數(shù)據(jù)附加到分析中,以便您或團隊中的其他人員可以嘗試重現(xiàn)您的結(jié)果。
在NVIDIA?(英偉達?)中,我們將性能分析視為一個科學(xué)流程,我們提供與分析相關(guān)的所有repro數(shù)據(jù),并鼓勵同事重新繪制并審核我們的結(jié)果。根據(jù)我們的經(jīng)驗,在進行性能優(yōu)化嘗試(無論是否成功)之前和之后捕獲幀也是一種很好的做法,分析硬件度量標(biāo)準(zhǔn)如何變化并從結(jié)果中學(xué)習(xí)。
關(guān)于Nsight幀捕獲的補充說明:
-
對于Nsight框架,無論您的應(yīng)用程序是以窗口模式,全屏模式還是全屏無邊界模式運行都無所謂,因為Nsight總是在隱藏窗口中運行框架。只要確保分辨率和圖形設(shè)置是你想要分析的。
-
對于DX12應(yīng)用程序,我們假設(shè)沒有使用異步計算,否則某些硬件度量可能會受到GPU上多個同時執(zhí)行的工作負(fù)載的影響。到目前為止,對于所有基于PerfWorks的分析,我們建議禁用在DX12應(yīng)用程序中使用異步計算。
-
關(guān)于DX12異步復(fù)制調(diào)用(在COPY隊列中),可以在幀捕獲中使用這些調(diào)用,但是您應(yīng)該知道,PerfWorks和Nsight目前不會單獨分析COPY隊列調(diào)用。因此,與其他DIRECT隊列調(diào)用并行執(zhí)行的任何COPY隊列調(diào)用都可能會影響這些工作負(fù)載中的GPU DRAM流量。
-
將該exe文件拖放到“Nsight HUD啟動器”將不適用于UWP應(yīng)用程序。在對UWP Nsight推出的做法,目前只能通過Visual Studio IDE中的支持。
第3步:分解GPU幀時間
GPU時間的自頂向下查看是找出哪些性能指標(biāo)/工作負(fù)載在一個幀中最昂貴的好方法。對于HBAO +DX11測試應(yīng)用程序,在GeForce GTX 1060 6GB上渲染SSAO為4K,在Nsight的Scrubber中,GPU幀時間分解如下所示:
圖1. Nsight中Scrubber的示例GPU幀時間細分:Visual Studio Edition 5.5。
在“Perf Markers”行中,Scrubber顯示通過D3D時間戳查詢測量的每個工作負(fù)載的GPU時間,以及每個工作負(fù)載正在使用的GPU幀時間百分比(排除當(dāng)前調(diào)用)。在圖1的例子中,這一幀中哪個工作負(fù)載最為昂貴是顯而易見的:“DrawCoarseAOPS”,占GPU時間的49.1%。
注意:要重新顯示此結(jié)果,可以從GitHub下載HBAO +源代碼版本3.1,然后在Visual Studio中運行“SampleApp_D3D11”項目。要使RenderAO調(diào)用發(fā)出性能標(biāo)記,可以在GFSDK_SSAO_D3D11 - >項目屬性 - > C / C + - >預(yù)處理器中定義ENABLE_PERF_MARKERS = 1。為了記錄,這里是框架的樣子:
步驟4:啟動Nsight Range Profiler
您可以打開您在步驟2中導(dǎo)出到磁盤的幀捕獲的Visual Studio解決方案文件,在Release x64中構(gòu)建解決方案,然后轉(zhuǎn)到Visual Studio中的Nsight菜單,然后單擊“開始圖形調(diào)試”。
要到達Nsight Range Profiler,您可以啟動Nsight幀捕捉EXE,然后:
-
按CTRL-Z然后按空格鍵
-
ALT-Tab到您的Visual Studio窗口
-
找到Nsight在那里添加的Scrubber選項卡
-
右鍵單擊您想要分析的工作負(fù)載,然后單擊“Profile [Perf Markers] ...”
注意:如果由于某種原因,CTRL-Z + SPACE不適用于您的應(yīng)用程序,您可以ALT-Tab到Visual Studio,然后單擊Visual Studio - > Nsight菜單 - >“暫停和捕獲幀”。
我們通過右鍵單擊洗滌器中的“DrawCoarseAOPS”框并執(zhí)行“Profile [Perf Markers] DrawCoarseAOPS”,從步驟3的“DrawCoarseAOPS”工作負(fù)載調(diào)用Range Profiler(僅通過分析此調(diào)用范圍,除此之外別無其他)
圖2.從Scrubber窗口為給定的工作負(fù)載啟動Nsight Range Profiler。
Range Profiler在Nsight幀捕獲中注入PerfWorks調(diào)用,并為指定的工作負(fù)載收集一組PerfWorks度量。分析完成后,Nsight將在Scrubber下方的Range Profiler窗口的新部分中顯示收集的度量標(biāo)準(zhǔn)。
第5步:檢查頂級SOL和高速緩存命中率
我們首先檢查Range Profiler的“Pipeline Overview”Summary部分的指標(biāo)。這只是PerfWorks衡量當(dāng)前工作負(fù)載的一個視圖。通過將鼠標(biāo)懸停在任何指標(biāo)上,實際的Perfworks指標(biāo)名稱將顯示在工具提示中:
圖3.顯示PerfWorks度量名稱和描述的Nsight Range Profiler工具提示。
5.1。每單位SOL%度量標(biāo)準(zhǔn)
要查看每個工作負(fù)載的首要頂級指標(biāo)是GPU的每單元SOL%指標(biāo)。這些傳達了每個單元與其最大理論吞吐量或光速(SOL)的接近程度。在高層次上,可以將每單元SOL%度量設(shè)想為實現(xiàn)的吞吐量與SOL吞吐量的比率。但是,對于具有多個子單元或并發(fā)數(shù)據(jù)路徑的單元,每單元SOL%是所有子單元和數(shù)據(jù)路徑的所有子SOL標(biāo)準(zhǔn)的最大值。
注:如果您不熟悉GPU中設(shè)備的名稱,請閱讀以下博客文章,其中提供了邏輯圖形管道如何映射到GPU架構(gòu)中的GPU單元的高級概述:“三角形的壽命- NVIDIA的邏輯管道“,以及GTC 2016演示文稿中的第7至第25張幻燈片:”GPU驅(qū)動渲染“。在這種情況下:
-
“IA”(Input Assembler)加載索引和頂點(在頂點著色器被調(diào)用之前)。
-
SM(流式多處理器)運行著色器。
-
L2是連接到每個DRAM分區(qū)的二級緩存。
-
CROP的顏色寫入和混合渲染目標(biāo)。
-
ZROP進行深度模板測試。
-
DRAM(范圍圖中的“內(nèi)存”)是GPU視頻內(nèi)存。
注意:在Nsight Range Profiler結(jié)果中,通過在管道概覽中選擇“Range Diagram”,可以找到圖形管道的簡化視圖及其與GPU單元的映射。在該圖中,每單位SOL%值顯示為綠色條形:
圖4. Nsight Range Profiler:流水線概覽 - >范圍圖。
如圖4所示,當(dāng)今的GPU不是一個簡單的線性流水線(A→B→C→...),而是一個互連單元網(wǎng)絡(luò)(SM < - > TEX < - > L2,SM- > CROP < - > L2等)。簡單的“瓶頸”計算依賴于每個單元的固定上行和下行接口,但不足以推斷GPU的性能。因此,在進行我們的分析時,我們主要考察每個單位的SOL%度量,以確定單位和/或限制性能的問題。下一節(jié)將詳細討論這種方法。
5.2。“頂級SOL單位”
在我們的性能分類方法論中,我們始終始于查看前5個SOL單位及其相關(guān)的SOL%度量。這些是限制此工作負(fù)載的GPU性能的前5個硬件單元。Nsight Range Profiler在Pipeline Overview - Summary部分顯示前5個SOL%指標(biāo)(又名“頂級SOL”),例如:
圖5. Range Profiler中的“Top SOLs”示例 - > Nsight中的Pipeline Overview:Visual Studio Edition 5.5。
情況1:SOL%> 80%
如果頂層SOL%值大于80%,那么我們知道GPU上的配置文件工作負(fù)載運行非常高效(接近最大吞吐量),為了加快速度,應(yīng)該嘗試從頂層SOL單元中移除工作,它到另一個單位。例如,對于SM作為SOL%> 80%的頂級SOL單元的工作負(fù)載,可以嘗試機會性地跳過指令組,或考慮將某些計算移動到查找表。另一個例子是將結(jié)構(gòu)化緩沖區(qū)加載移動到在統(tǒng)一訪問結(jié)構(gòu)化緩沖區(qū)(所有線程加載來自相同地址的數(shù)據(jù))中的著色器中的恒定緩沖區(qū)加載,以及受紋理吞吐量限制的工作負(fù)載(因為結(jié)構(gòu)化緩沖區(qū)通過TEX單元加載)。
情況2:頂部SOL%<60%
如果最高SOL%值<60%,這意味著頂級SOL單元和所有其他具有較低SOL%的GPU單元未充分利用(空閑周期),運行效率低下(失速周期),或者未達到其快速路徑,原因是他們給出的工作量的細節(jié)。這些情況的例子包括:
-
該應(yīng)用程序部分受CPU限制(參見第6.1.1節(jié));
-
大量等待空閑命令或圖形< - >計算開關(guān)反復(fù)排空GPU管線(參見第6.1.2節(jié));
-
TEX從具有格式,維度或過濾器模式的紋理對象中提取數(shù)據(jù),使其在設(shè)計時以較低的吞吐量運行(請參閱這些用于GTX 1080的綜合基準(zhǔn)測試)。例如,當(dāng)采用三線性濾波對三維紋理進行采樣時,預(yù)計有50%的TEX SOL%;
-
內(nèi)存子系統(tǒng)效率低下,例如TEX或L2單元中高速緩存命中率低,導(dǎo)致DRAM SOL%低的DRAM訪問稀疏,VB / IB / CB / TEX從系統(tǒng)內(nèi)存取代GPU DRAM;
-
輸入組件獲取32位索引緩沖區(qū)(半速率與16位索引相比)。
注意:在這種情況下,我們可以使用最高SOL%值來導(dǎo)出可通過降低低效率在此工作負(fù)載上實現(xiàn)的最大增益的上限:如果給定的工作負(fù)載在其SOL的50%處運行,并且假設(shè)可以通過減少內(nèi)部低效率將SOL%提高到90%,我們知道工作負(fù)載的最大預(yù)期收益為90/50 = 1.8x = 80%。
情況3:[60,80]中的最高SOL%
在這種情況下(灰色區(qū)域),我們遵循情況1(高位SOL%)和情況2(低位SOL%)的方法。
注:每單元SOL%度量標(biāo)準(zhǔn)都是相對于GPU周期(掛鐘)而定義的,這可能與活動周期(硬件單元不空閑的周期)不同。我們定義它們相對于經(jīng)過周期而不是每單位有效周期的主要原因是通過給出它們所有的公分母來使SOL%指標(biāo)具有可比性。定義它們相對于經(jīng)過周期的另一個好處是任何限制整體GPU性能的GPU空閑周期都會被報告為該工作負(fù)載的最低SOL%值(我們的SOL引導(dǎo)分類中的頂級度量標(biāo)準(zhǔn))。
5.3。次要SOL單位和TEX和L2命中率
Nsight Range Profiler報告前5個SOL單元的原因不僅僅是最大的一個,因為可能有多個硬件單元彼此交互,并且都在一定程度上限制了性能。所以我們建議根據(jù)SOL%值手動對SOL單元進行聚類。(實際上,10%的增量似乎可以很好地定義這些集群,但我們建議手動執(zhí)行集群以避免遺漏任何內(nèi)容。)
注意:我們還建議查看距離分析器“內(nèi)存”部分中顯示的TEX(L1)和L2命中率。一般來說,大于90%的命中率很好,80%到90%之間好,80%以下(可能會顯著限制性能)。
全屏HBAO +模糊工作負(fù)載與前5個SOL:
SM:94.5%|TEX:94.5%|L2:37.3%|作物:35.9%|DRAM:27.7%
...既是SM又是TEX限制。由于SM和TEX SOL%值是相同的,我們可以推斷出SM性能很可能受SM和TEX單元之間接口吞吐量的限制:SM請求TEX或TEX將數(shù)據(jù)返回給SM 。
它具有TEX命中率88.9%和L2命中率87.3%。
在“TEX-Interface Limited Workload”附錄中查看此工作負(fù)載的研究。
從HBAO +例子中轉(zhuǎn)移出來,下面是我們最近分析的一些典型的游戲引擎工作負(fù)載。
具有頂級SOL的SSR工作負(fù)載:
SM:49.1%|L2:36.8%|TEX:35.8%|DRAM:33.5%|CROP:0.0%
...將SM作為主要限制器,將L2,TEX和DRAM作為次要限制器,TEX命中率為54.6%,L2命中率為76.4%。這種較差的TEX命中率可以解釋SM SOL%較低:由于TEX命中率較差(很可能是由于相鄰像素獲取了很遠的紋理元素),因此SM看到的平均TEX延遲比通常更高,更具挑戰(zhàn)性隱藏。
注意:這里的活動單元實際上是一個依賴鏈:SM - > TEX - > L2 - > DRAM。
此頂級SOL的GBuffer填充工作負(fù)載:
TEX:54.7%|SM:46.0%|DRAM:37.2%|L2:30.7%|CROP:22.0%
...將TEX和SM作為主要限制器,將DRAM和L2作為次要限制器,TEX命中率為92.5%,L2命中率為72.7%。
這款平鋪照明計算著色器具有頂級SOL:
SM:70.4%|L2:67.5%|TEX:49.3%|DRAM:42.6%|CROP:0.0%
...以SM&L2為主要限制器,TEX&DRAM為次要限制器,TEX命中率為64.3%,L2命中率為85.2%。
這個帶有頂級SOL的陰影貼圖生成工作負(fù)載:
IA:31.6%|DRAM:19.8%|L2:16.3%|VAF:12.4%|CROP:0.0%
...是IA限制的(輸入匯編器)并且具有較低的SOL%。在這種情況下,將索引緩沖區(qū)格式從32位更改為16位有幫助。TEX命中率無關(guān)緊要,因為TEX不在前5名SOL單位中。L2命中率為62.6%。
第6步:了解性能限制器
完成第5步后,我們知道每個感興趣工作負(fù)載的頂級SOL單元(GPU單元名稱和最大吞吐量的百分比),以及TEX和L2命中率。
我們知道,頂級的SOL GPU單元正在限制正在研究的工作負(fù)載的性能,因為這些單元正在運行最接近其最大吞吐量的單元。我們現(xiàn)在需要了解什么是限制這些top-SOL單元的性能。
6.1。如果頂部SOL%為低
如上面第5.2.2節(jié)所述,有多種可能的原因。我們經(jīng)常將這些稱為病理 - 并且與現(xiàn)實生活中的患者一樣,工作負(fù)荷可能同時遭受多種病癥的影響。我們首先檢查以下指標(biāo)的值:“GPU空閑%”和“SM單元活動百分比”。
6.1.1。“GPU空閑%”度量標(biāo)準(zhǔn)
Range Profiler的“GPU Idle%”度量標(biāo)準(zhǔn)映射到“gr__idle_pct”PerfWorks度量標(biāo)準(zhǔn)。它是當(dāng)前工作負(fù)載下整個圖形和計算硬件管道閑置的GPU經(jīng)過周期的百分比。這些“GPU空閑”周期是CPU無法為GPU提供足夠快的命令的周期,因此GPU管線完全是空的,無需處理任何工作。請注意,Wait For Idle命令導(dǎo)致的管道排空不計為“GPU空閑”。
如果針對任何給定的GPU工作負(fù)載看到此度量標(biāo)準(zhǔn)大于1%,那么您知道此工作負(fù)載由于某種原因受CPU限制,并且此CPU工作負(fù)載的性能影響至少為1%。在這種情況下,我們建議測量以下CPU調(diào)用花費的每個工作負(fù)載的總CPU時間,然后嘗試最小化最昂貴的CPU時間:
對于DX11:
-
沖洗{,1}
-
地圖
-
UpdateSubresource {,1}
對于DX12:
-
等待
-
ExecuteCommandLists
對于DX11和DX12:
-
任何創(chuàng)建或釋放呼叫
DX11說明:
-
ID3D11DeviceContext :: Flush強制執(zhí)行命令緩沖區(qū)啟動,這可能需要Flush()調(diào)用在CPU上停止。
-
在連續(xù)幀中映射相同的分段資源時,在STAGING資源上調(diào)用ID3D11DeviceContext :: Map可能會導(dǎo)致CPU因資源爭用而停頓。在這種情況下,當(dāng)前幀中的Map調(diào)用必須在內(nèi)部等待,直到前一幀(使用相同的資源)在返回之前已經(jīng)被處理。
-
使用DX11_MAP_WRITE_DISCARD調(diào)用ID3D11DeviceContext :: Map可能會導(dǎo)致CPU由于驅(qū)動程序用盡版本空間而停頓。這是因為每次執(zhí)行Map(WRITE_DISCARD)調(diào)用時,驅(qū)動程序都會返回一個指向固定大小內(nèi)存池的新指針。如果驅(qū)動程序用盡版本空間,Map調(diào)用將停止。
DX12注意事項:
-
每個ExecuteCommandLists(ECL)調(diào)用都有一些與之關(guān)聯(lián)的GPU空閑開銷,用于啟動新的命令緩沖區(qū)。因此,為了減少GPU空閑時間,我們建議將所有命令列表分配到盡可能少的ECL調(diào)用,除非您真的想要在幀中的某些點發(fā)生命令緩沖區(qū)啟動(例如,為了減少VR應(yīng)用程序中的輸入延遲在飛行中有一個框架)。
-
當(dāng)應(yīng)用程序調(diào)用ID3D12CommandQueue :: Wait時,操作系統(tǒng)(Windows 10)將暫停向該命令隊列的GPU提交新的命令緩沖區(qū),直到等待調(diào)用返回。
注意:每個API調(diào)用的CPU時間可以使用Nsight通過捕獲一個幀,然后進入Visual Studio - > Nsight - > Windows - > Events來測量:
6.1.2。“SM單元有效百分比”指標(biāo)
“SM單元活躍%”度量標(biāo)準(zhǔn)報告每個SM實例至少有1個warp(32個線程)活動周期的百分比,在所有SM實例中平均。請注意,正在等待內(nèi)存請求返回的變形會被記錄為“正在運行”/正在飛行中。
在Nsight:Visual Studio Edition 5.5中,此度量標(biāo)準(zhǔn)顯示在“管道總覽匯總”中的“范圍分析器結(jié)果”中。
對于全屏四元組或計算著色器工作負(fù)載,SM應(yīng)該在超過95%的工作負(fù)載中處于活動狀態(tài)。如果不是,那么很可能SM之間存在不平衡,一些SM處于空閑狀態(tài)(沒有活動的翹曲),而其他SM處于活動狀態(tài)(至少有一個活動翹曲)。運行具有非均勻扭曲延遲的著色器時會發(fā)生這種情況。此外,具有少量小線程組的序列化調(diào)度調(diào)用不能足夠?qū)捯蕴畛銰PU上的所有SM。
如果對于任何幾何渲染工作負(fù)載,SM活動百分比低于95%,您知道通過將異步計算工作與它重疊,可以在此工作負(fù)載上獲得性能提升。在DX12和Vulkan上,這可以通過使用Compute-only隊列來完成。請注意,即使SM活動百分比接近100%,也可以從異步計算獲得加速,因為SM可能被跟蹤為活動狀態(tài),但可能能夠承受更多活動狀態(tài)。
對于任何工作負(fù)載而言,“SM單元活動百分比”可能低于95%的另一個原因是頻繁的GPU管線消耗(等待空閑命令,又名WFI),這可能是由以下原因造成的:
-
-
-
問題:出于著色器調(diào)度原因,HS和DS處于活動狀態(tài)時進行很多狀態(tài)更改會導(dǎo)致SM消失。
-
解決方案:盡量減少具有細化著色器的工作負(fù)載中的狀態(tài)更改(包括資源綁定)的數(shù)量。
-
-
問題:給定隊列上每批次的背靠背ResourceBarrier調(diào)用可能導(dǎo)致該隊列上的所有GPU工作都耗盡。
-
解決方案:為了最大限度地減少ResourceBarrier調(diào)用的性能影響,重要的是盡量減少執(zhí)行ResourceBarrier調(diào)用的幀中的位置數(shù)量。
-
-
問題:默認(rèn)情況下,具有綁定無人機的后續(xù)渲染調(diào)用通常由我們的驅(qū)動程序注入的GPU WFI命令進行保守分隔,以防止任何數(shù)據(jù)危害。
-
解決方案:可以使用以下調(diào)用來禁用無人機相關(guān)的等待空閑命令的插入:NvAPI_D3D11_ {Begin,End} UAVOverlap或NvAPI_D3D11_BeginUAVOverlapEx。
-
請注意,在DX12,OpenGL和Vulkan中,無人機相關(guān)的等待空閑命令由應(yīng)用程序使用API調(diào)用(ResourceBarrier,glMemoryBarrier或vkCmdPipelineBarrier)顯式控制。
-
-
問題:在同一硬件隊列中的Draw和Dispatch調(diào)用之間切換會導(dǎo)致GPU WFI執(zhí)行。此外,在僅計算工作負(fù)載中執(zhí)行非CS狀態(tài)設(shè)置調(diào)用(例如,映射綁定到CS和圖形著色器階段的常量緩沖區(qū))可能會導(dǎo)致WFI執(zhí)行。
-
解決方案:批處理所有計算工作,并且不交叉圖形和計算API調(diào)用,包括Map(WRITE_DISCARD)調(diào)用在所有著色器階段綁定的“粘性”資源上。
-
頻繁計算< - >圖形開關(guān)在同一個DX11上下文中或在同一個DX12隊列中。
-
在DX11上,多個渲染調(diào)用具有相同的無人機界限,并且沒有提供給我們驅(qū)動程序的“無人機重疊”提示。
-
在DX12上,ResourceBarrier在障礙之間幾乎沒有任何工作。
-
數(shù)百在使用鑲嵌著色器/或幾何著色器的工作負(fù)載狀態(tài)的變化(除了硫苷被創(chuàng)建作為直通快速硫苷,使用NVAPI為DX11和DX12,或NV_geometry_shader_passthrough為GL)。
-
6.2。如果頂部SOL單位是SM
如果SM是最高SOL單位(或者以SOL%計),我們將分析Nsight Range Profiler中“SM問題利用率”指標(biāo)的值。
SM單元是一個復(fù)雜單元,包含多個子單元,每個子單元具有相關(guān)的SOL%度量。PerfWorks庫允許查詢這些SM子SOL%指標(biāo)之一:“sm__issue_active_per_elapsed_cycle_sol_pct”,該指標(biāo)在范圍分析器中名為“SM IssueUtilizing Per Eilpsed Cycle”中公開。此度量是SM調(diào)度程序發(fā)出至少一條指令的已用周期的百分比。如果在給定的工作負(fù)載中,我們有“每個經(jīng)過周期的SM問題利用率”==“SM SOL%”,那么我們知道最高SM子限制器是SM指令調(diào)度器,即工作負(fù)載是SM問題有限。
Range Profiler還在名稱“SM Issue Utilization Per Active Cycle”中公開“sm__issue_active_per_active_cycle_sol_pct”度量標(biāo)準(zhǔn)。與以前的度量唯一的區(qū)別在于,每個活動周期1通過SM活動周期數(shù)(具有至少一個活動激活的周期)而不是經(jīng)過的周期(掛鐘)進行標(biāo)準(zhǔn)化。
“每個活動周期的SM問題利用率”度量標(biāo)準(zhǔn)對于確定給定的工作負(fù)載是否部分受“SM占用率”(“sm__active_warps_avg_per_active_cycle”PerfWorks度量標(biāo)準(zhǔn))限制很有用。
案例1:“每個活動周期的SM問題利用率”> 80%
如果SM是最高的SOL單位,并且“每個活動周期的SM問題利用率”大于80%,那么當(dāng)前工作負(fù)載主要受SM調(diào)度程序問題率的限制,因此增加SM占用率不會顯著提高性能(在工作量最少不超過5%)。
在這種情況下,性能分類過程的下一步是計算出哪些指令正在使SM調(diào)度器的帶寬飽和。通常,這是數(shù)學(xué)指令(FP32或整數(shù)操作數(shù)),但也可以是內(nèi)存指令,如紋理提取或共享內(nèi)存訪問。此外,TEX指令(SRV和UAV訪問)不太可能限制SM作為頂級SOL單元和SM問題利用率> 80%的工作負(fù)載的性能,除非TEX單元的SOL%值也接近于SM。
案例2:“每個活動周期的SM問題利用率”<60%
如本次GTC2013會議幻燈片15(t = 14分鐘)所述,當(dāng)給定的warp指令不能發(fā)出時(因為它的操作數(shù)沒有準(zhǔn)備好或者因為它需要執(zhí)行的流水線子單元沒有準(zhǔn)備好 - 我們呼叫這是一個扭曲失速),那么SM指令調(diào)度器會嘗試通過切換到不同的主動變形來隱藏延遲。因此,有兩種方法可以幫助SM調(diào)度程序為每個SM活動周期發(fā)出更多指令:
-
增加SM占用率(調(diào)度程序可以切換到的活動warp的數(shù)量)和
-
減少SM發(fā)布延遲時間(所以經(jīng)線保持停滯狀態(tài)的周期更少)。
方法1:增加SM入住率
如果SM是最高SOL單位(或關(guān)閉),“SM SOL%”<80%,并且“?每次活動周期的SM問題利用率”<60%,則增加SM入住率應(yīng)該可以提高性能。
為了增加SM占用率,首先必須弄清楚限制它的因素。
像素和計算著色器最常見的SM占用限制器是著色器使用的每個線程的硬件寄存器數(shù)量。
硬件寄存器計數(shù)對最大理論占用率(每個活動周期的活動變形數(shù))的影響可在我們的CUDA占用率計算器中找到。以下是“計算能力”6.1的理論占有率圖,其中包括所有的GeForce GTX 10XX和Quadro Pxxxx GPU(GP10X):
圖6.“計算能力”的CUDA占用計算器圖表6.1。
除寄存器外,以下資源還可限制Maxwell,Pascal和Volta GPU上的SM占用率:
-
對于圖形著色器:
-
頂點著色器輸出屬性的總大小。
-
像素著色器輸入屬性的總大小。
-
HS,DS或GS的輸入和輸出屬性的總大小。
-
對于像素著色器,像素扭曲的亂序完成(通常由于諸如動態(tài)循環(huán)或早退出分支的動態(tài)控制流)。請注意CS沒有這個問題,因為CS線程組可以按任意順序完成。請參閱我們GDC 2016演講Gareth Thomas&Alex Dunn的“Practical DirectX 12”演講幻燈片。
-
-
對于計算著色器:
-
線程組大小可以直接影響SM占用率,因為線程組的線程組以全部或全部方式在SM上啟動(即,線程組的所有線程都具有必需的資源并將一起啟動,或者不會啟動將)。線程組大小越大,像共享內(nèi)存和寄存器文件這樣的資源量化越粗糙。雖然有些算法可能真的需要大型線程組,但在所有其他情況下,開發(fā)人員應(yīng)盡量將線程組大小限制為64或32個線程。這是因為64或32線程的線程組為我們的著色器編譯器提供了最大的靈活性,為著色器程序選擇最佳可能的寄存器目標(biāo)。
-
此外,對于具有高寄存器使用率(> = 64)以及SM(Group H MemoryLarrierWithGroupSync()中的高線程組屏障停頓時間的著色器,將線程組大小降低為32可能會產(chǎn)生加速比,與64相比較。 > = 64寄存器指導(dǎo)可確保每個SM限制的32個最大線程組(CUDA占用率計算器中與架構(gòu)相關(guān)的“線程塊/多處理器”限制)不會成為SM主要占用限制器。
-
每個線程組分配的共享內(nèi)存字節(jié)總數(shù)也可以直接影響SM占用率,這可以通過將各種數(shù)字插入CUDA占用率計算器中看出。
-
我們關(guān)于實現(xiàn)占用率的CUDA Nsight文檔頁面包括計算著色器的一些額外可能的SM占用限制器:
-
線程組內(nèi)的工作負(fù)載不平衡。
-
啟動的線程組太少。這對于圖形著色器來說也是一個問題,它沒有啟動足夠的warps來完全占用GPU Wait For Id之間的SM。
注意:實際上有兩種方法可以減少線程組大?。?/span>
-
方法1:將線程組大小降低N倍,同時將網(wǎng)格發(fā)射維度增加N.參見上文。
-
方法2:將N> = 2個線程的工作合并到一個線程中。這允許通過寄存器在N個合并線程之間共享公共數(shù)據(jù),或者在寄存器中執(zhí)行減少操作,而不是使用原子操作符(例如HLSL中的InterlockedMin)在共享內(nèi)存中執(zhí)行減少操作。此外,這種方法還具有在N個合并線程中自動分?jǐn)偩€程組統(tǒng)一操作的優(yōu)點。但是,應(yīng)該警惕這種方法可能導(dǎo)致登記數(shù)量膨脹。
注意:如果您想了解某個給定工作負(fù)載的SM占用量是否主要針對某個全屏Pixel Shader或某個計算著色器的寄存器數(shù)限制,則可以執(zhí)行以下操作:
-
在Scrubber中添加...“程序范圍”,并找到您有興趣研究的著色器程序范圍。右鍵單擊您的程序范圍,啟動Range Profiler并檢查管道總覽摘要中的“SM占用率”值。
-
點擊Scrubber中的“Time(ms)”行,在Range中選擇一些渲染調(diào)用。將選項卡切換到API檢查器,選擇占用工作負(fù)載(PS或CS)中大部分周期的著色器階段,然后單擊著色器名稱旁邊的“統(tǒng)計”鏈接。
-
這會打開“Shaders”Nsight窗口(見下面的屏幕截圖),其中顯示了著色器的硬件寄存器數(shù)量,在“Regs”列中。請注意,您可能需要等待幾秒鐘才能填充著色器統(tǒng)計信息。
-
使用圖6中的CUDA占用率計算器圖查找與此寄存器計數(shù)相關(guān)的最大理論占用率,并將其與該范圍分析器為該著色器報告的實際“SM占用率”進行比較。
-
如果實現(xiàn)的占用率遠低于最大占用率,那么您知道SM占用率受限于每個線程的寄存器數(shù)量以外的其他因素。
圖7. Nsight的“Shaders View”,顯示“Regs”列中每個著色器的硬件寄存器數(shù)量。
為了減少為給定著色器分配的寄存器總數(shù),可以查看DX著色器組件并研究著色器每個分支中使用的寄存器數(shù)量。硬件需要為最需要寄存器的分支分配寄存器,并且跳過該分支的經(jīng)線以不理想的SM占用情況運行。
對于全屏通道(像素或計算著色器),解決此問題的典型方法是運行預(yù)處理,將像素分為不同的區(qū)域,并針對每個區(qū)域運行不同的著色器置換:
-
對于計算著色器,此SIGGRAPH 2016演示文稿介紹了一種使用DispatchIndirect調(diào)用將專用計算著色器應(yīng)用于屏幕上不同圖塊的解決方案,每個著色器排列使用可變數(shù)量的線程塊:“Uncharted 4中的延遲照明” - Ramy El Garawany(淘氣狗)。
-
對于像素著色器,可以使用不同的專業(yè)化方法:全屏模板緩沖區(qū)可以在預(yù)處理中填充以對像素進行分類。然后,通過在像素著色器執(zhí)行之前(這應(yīng)該由我們的驅(qū)動程序自動完成)依靠模板測試來發(fā)生多個繪制調(diào)用,并且使用模板測試來丟棄當(dāng)前著色器置換沒有的像素觸摸。此GDC 2013演示文稿使用此方法優(yōu)化MSAA延遲渲染:“孤島危機3渲染技術(shù)” - Tiago Sousa,Carsten Wenzel,Chris Raine(Crytek)。
最后,為了更好地理解給定計算著色器的SM占用限制,您可以使用我們的CUDA占位計算器電子表格。要使用它,只需填寫GPU的CUDA計算能力以及著色器的資源使用情況(線程組大小,來自Shader視圖的寄存器計數(shù)以及共享內(nèi)存大?。ㄒ宰止?jié)為單位))。
方法2:減少SM失步延遲
除了增加SM占用率外,還有另一種方法可以增加SM問題利用率:通過減少SM發(fā)布 - 停止周期的數(shù)量。這些是指令執(zhí)行周期之間的SM活動周期,在此期間,由于其操作數(shù)未準(zhǔn)備就緒或由于數(shù)據(jù)路徑上的資源爭用而導(dǎo)致該指令需要在其上執(zhí)行,因此warp指令被暫停。
如果所有著色器都在做數(shù)學(xué)運算和紋理提取,并且每個活動周期的SM問題利用率很低,那么可以合理地假設(shè)大多數(shù)停頓周期都來自于紋理提取結(jié)果的依賴關(guān)系,我們經(jīng)常稱為“紋理延遲”。在這種情況下:
-
如果著色器包含一個可以在著色器編譯時可以知道迭代次數(shù)的循環(huán)(可能通過每個循環(huán)次數(shù)使用不同的著色器置換),那么嘗試強制FXC通過使用循環(huán)中的[unroll]循環(huán)屬性來完全展開循環(huán)HLSL。
-
如果著色器正在執(zhí)行無法完全展開的動態(tài)循環(huán)(例如光線循環(huán)循環(huán)),請嘗試對紋理獲取指令進行批處理,以減少TEX依賴性延遲的數(shù)量(通過將獨立紋理拾取分批次編組為2到4在HLSL層面的背靠背說明)。
請參閱“優(yōu)化光線行進循環(huán)”附錄。 -
如果著色器對給定紋理的每個像素的所有MSAA子采樣進行迭代,則可以在該紋理的單個TEX批處理指令中一起提取所有子采樣。由于MSAA子采樣在DRAM中彼此相鄰存儲,因此將它們一起提取可以最大化TEX命中率。
-
如果紋理加載是基于條件的,那么大多數(shù)時間都是真實的(例如,如果(idx
-
嘗試通過改進TEX和L2緩存命中率來減少TEX延遲。通過調(diào)整采樣模式以使相鄰像素/線程獲取更多相鄰紋理像素,通過使用mipmap(如果適用)以及通過減小紋理尺寸和使用更緊湊的紋理格式,可以提高TEX&L2命中率。
-
嘗試減少執(zhí)行的TEX指令的數(shù)量(可能使用每個紋理指令使用分支,將其編譯為TEX指令謂詞,請參閱FXAA 3.11 HLSL的示例,例如:“if(!doneN)lumaEndN = FxaaLuma(...);”) 。
案例3:[60,80]中的問題利用率%
在這種情況下,我們遵循案例1(高問題利用率)和案例2(低問題利用率)的方法。
6.3。如果頂部SOL單元不是SM
6.3.1。如果頂層SOL單元是TEX,L2或DRAM
如果頂層SOL單元不是SM,而是其中一個內(nèi)存子系統(tǒng)單元(TEX-L1,L2和DRAM),則可能導(dǎo)致性能較差的根本原因是TEX或L2緩存抖動-GPU友好的訪問模式(通常,在一個warp中相鄰的線程訪問相距甚遠的內(nèi)存)。在這種情況下,頂部限制單元可能是TEX或L2,但根本原因可能在SM執(zhí)行的著色器中,所以使用第6.2節(jié)中的方法(如果頂部SOL單元是SM )。
如果頂級SOL單元是DRAM,并且其SOL%值不差(> 60%),那么這個工作負(fù)載是DRAM吞吐量受限的,并且將其與另一個通道合并應(yīng)該加速該幀。一個典型的例子是將伽馬校正通道與另一個后處理通道合并。
6.3.2。如果頂部SOL單位是CROP或ZROP
如果CROP是頂級SOL單元,則可以嘗試使用較小的渲染目標(biāo)格式(例如R11G11B10F而不是RGBA16F),并且如果使用多個渲染目標(biāo),則可以嘗試減少渲染目標(biāo)的數(shù)量。此外,更積極地殺死像素著色器中的像素可能是值得的(例如,對于某些透明效果,丟棄具有小于1%不透明度的像素)。查看此博客文章,獲取優(yōu)化透明度渲染的更多可能策略:“透明度(或半透明度)渲染”。
如果ZROP是頂層SOL單元,則可以嘗試使用較小的深度格式(例如D16代替D24X8用于陰影貼圖,或用D24S8代替D32S8),以及以前后順序繪制不透明物體,以便ZCULL (粗粒度深度測試)有機會在調(diào)用ZROP和像素著色器之前丟棄更多的像素。
6.3.3。如果頂部SOL單位是IA
如前所述,IA會執(zhí)行索引緩沖區(qū)和頂點緩沖區(qū)加載,以收集頂點著色器的輸入頂點。如果IA是頂級SOL單元,則可以嘗試使用16位索引緩沖區(qū)而不是32位索引緩沖區(qū)。如果這不會增加IA SOL%,則可以嘗試優(yōu)化頂點重用和局部性的幾何圖形。此外,從其余屬性中分離出位置流對于z-only或陰影貼圖渲染可能是有益的。
概要
為了結(jié)束,我們的SOL引導(dǎo)式性能分類方法針對任何給定的GPU工作負(fù)載執(zhí)行以下操作:
-
檢查“SOL SOL%”值(5.2節(jié)和5.3節(jié))。
-
如果> 80%=>(A)嘗試從頂層SOL單元中取出工件(見第5.2.1節(jié))。
-
如果<60%=>(B)嘗試增加SOL%(5.2.2和6.1節(jié))。
-
(A)和(B)都可以。
-
-
如果SM是最高SOL單位(或以SOL%計)或“SM SOL%”低于80%:
-
如果> 80%=>(C)嘗試機會性地跳過指令組或考慮將某些計算移動到查找表(見第6.2.1節(jié))。
-
如果<60%=>(D)嘗試增加SM占有率(飛行中活動的經(jīng)紗數(shù)量)并減少SM發(fā)貨 - 停止周期的數(shù)量(見第6.2.2節(jié))。
-
其他人同時做(C)和(D)。
-
檢查“每個活動周期的SM問題利用率”值。
-
-
如果其他單位是頂級SOL單位,請嘗試減少發(fā)送到該單位的工作量。(見第6.3節(jié))。
要使用此方法,您只需要安裝Nsight:在PC上安裝Visual Studio Edition 5.5以及安裝最新的可用圖形驅(qū)動程序。
附錄:性能分類示例
示例1:TEX-Interface有限的工作負(fù)載
在GTX 1060 6GB @ 1506 Mhz上運行的HBAO +“DrawBlurXPS”全屏像素著色器工作負(fù)載在Nsight Range Profiler中具有以下指標(biāo):
-
頂部SOLs:SM:94.5%|TEX:94.5%|L2:37.2%|DRAM:27.6%
-
GPU空閑:0.0%=>不受CPU限制(參見第6.1.1節(jié))
-
SM單元有效:99.5%=>無SM閑置問題(參見第6.1.2節(jié))
-
SM問題使用率每循環(huán)周期:47.2%
-
每個活動周期的SM問題利用率:47.5%
-
SM占用:每個活動周期62.2個活動的經(jīng)紗
-
TEX命中率:88.9%
-
二級命中率:87.3%
分析:
-
由于SM SOL%和TEX SOL%都非常接近(實際上相等),所以我們知道工作負(fù)載受到SM和TEX單元之間接口吞吐量的限制。
-
由于SM和TEX SOL%很高(94.5%),我們知道工作負(fù)載完全受SM和TEX單位的吞吐量的限制(95%與SOL%值一樣高)。
-
由于每個活動周期的SM問題利用率遠低于80%,我們知道指令調(diào)度器的帶寬遠未達到飽和。因此,增加SM占用率(每個活動周期的活動經(jīng)紗數(shù)量)可能有助于理論上的幫助。但是由于SM SOL%(94.5%)太高,我們知道增加入住率并不會顯著提高績效。
-
TEX和L2的命中率很好(接近90%)。
結(jié)論:這個工作負(fù)載主要受SM-TEX接口帶寬的限制,唯一可以顯著加快執(zhí)行速度的方法是減少執(zhí)行的TEX指令的數(shù)量(例如,通過使用收集指令在一個TEX中執(zhí)行4個單通道負(fù)載指令,或通過計算每個線程的多個輸出值并通過寄存器共享紋理采樣)。
示例2:數(shù)學(xué)有限的工作負(fù)載
HBAO +“DrawCoarseAOPS”工作負(fù)載在GTX 1060 @ 1506 Mhz上的Range Profiler中具有以下指標(biāo):
-
頂部SOLs:SM:93.4%|TEX:71.9%|L2:50.1%|DRAM:27.3%|CROP:3.6%
-
GPU空閑:0.0%=>不受CPU限制(請參閱第6.1.1節(jié))
-
SM單元激活:99.5%=>沒有SM空閑問題(參見章節(jié)6.1.2)
-
每個周期的SM問題利用率:93.4%
-
每個活動周期的SM問題利用率:95.9%
頂部SOL分析:
-
最上面的SOL單元是SM,它的最大吞吐量為93.4%,輔助SOL單元(TEX,L2和DRAM)比SM SOL多20%,所以我們知道工作負(fù)載主要是SM通過限制。
-
第二個上限是TEX單位,以最大吞吐量的71.9%運行。
現(xiàn)在,讓我們進行以下思考實驗:如果此GPU中的TEX單元以某種方式無限快速完成,則工作負(fù)載仍將受到SM SM內(nèi)93%SM內(nèi)發(fā)生的工作的限制。這些工作中的一部分通常是來自著色器的紋理提取,因此如果TEX單元無限快地完成并且SM最初受TEX延遲限制,SM SOL可能會增加。但是,由于95%的價值與實踐中的SOL%值一樣高,我們知道SM SOL%無法通過使其他單位更快(或處理更少的工作)而顯著增加,因此我們知道唯一的顯著加速這一工作量的方法是找出SM內(nèi)部的性能限制器。
附加分析:
-
由于SM是最大限制因素,并且“每次經(jīng)過周期的SM問題利用率”==“SM SOL%”,因此我們知道此工作負(fù)載的最大SM子SOL度量標(biāo)準(zhǔn)為SM問題利用率%,即工作負(fù)載為主要受指令發(fā)行率的限制。
-
由于“每次活動周期的SM問題利用率”> 80%,我們知道工作負(fù)載不受SM占用率的明顯限制,也就是說,增加每個活動周期的活動warps數(shù)量并不會顯著提高性能。
-
我們可以推斷,性能不受紋理獲取指令的延遲的限制,否則我們將“SM活動周期的利用率”遠低于80%。
-
我們可以推斷性能不受TEX單元的限制,否則我們會讓TEX SOL%值更接近SM SOL%值。
結(jié)論:這個工作負(fù)載主要受著色器中數(shù)學(xué)指令的數(shù)量(FP32操作數(shù)和/或整數(shù)操作數(shù)和/或其他數(shù)學(xué)操作如rsqrt,pow,cos / sin等)的限制。為了加快速度,人們需要找到一種方法來以某種方式遮蔽較少的像素,或者每像素執(zhí)行較少的數(shù)學(xué)指令。
示例3:TEX-Latency有限的工作負(fù)載
現(xiàn)在,我們來看看https://github.com/NVIDIAGameWorks/D3DSamples中的“Advanced Motion Blur”DX11 SDK示例
默認(rèn)情況下,應(yīng)用程序以720p窗口模式運行。為了使它以4K全屏模式啟動,我在main.cpp中進行了以下編輯:
#if0deviceParams.startfull-screen=false;deviceParams.backBufferWidth=1280;deviceParams.backBufferHeight=720;#其他deviceParams.startfull-screen=true;deviceParams.backBufferWidth=3840;deviceParams.backBufferHeight=2160;#萬一
接下來,我們可以在main.cpp中手動插入一個工作負(fù)載標(biāo)記,它將被NSight攔截并在Range Profiler中成為“Perf Marker”范圍:
如果(g_view_mode==VIEW_MODE_FINAL){D3DPERF_BeginEvent(0x0,L“FinalPass”);//...ctx->Draw(6,0);D3DPERF_EndEvent();}
最后,我們可以按照第4節(jié)中的步驟使用Nsight Range Profiler來分析此工作負(fù)載。在GTX 1060 @ 1506 Mhz上,Range Profiler提供以下指標(biāo):
-
頂部SOLs:SM:40.7%|TEX:39.8%|L2:36.3%|作物:26.4%|DRAM:25.7%
-
GPU已用時間:0.70毫秒
-
GPU空閑:0.2%=>不受CPU限制(請參閱第6.1.1節(jié))
-
SM單元有效:97.4%=>無SM閑置問題(請參閱第6.1.2節(jié))
-
SM問題利用率每循環(huán)周期:40.7%
-
每個活動周期的SM問題利用率:41.8%
-
SM占用:每個活動周期37.0個活動經(jīng)紗
-
TEX命中率:80.1%
-
二級命中率:83.0%
分析:
-
頂級SOL%單位是SM和TEX。
-
最高的SOL%值低于60%,所以此工作負(fù)載在GPU上運行效率低下。
-
由于“每個活動周期的SM問題利用率”遠低于80%,并且TEX SOL%非常接近SM SOL%,所以工作負(fù)載受TEX延遲限制。
-
由于頂級SOL單位是SM,“SM SOL%”<80%和“每個活動周期的SM問題利用率”<60%(請參見第6.2.2節(jié)),因此工作負(fù)載也受SM占用限制。
-
TEX和L2命中率很好。
實驗:刪除提前退出
根據(jù)第6.2.2節(jié),我們知道,對于SM作為頂級SOL單元的工作負(fù)載,“SM SOL%”<80%和“每次活動周期的SM問題利用率”<60%,性能可能受到以下限制:
-
由于沒有足夠的指令級并行性來隱藏指令等待時間,所以出現(xiàn)高的問題延遲時間和/或
-
SM入住率低(由于沒有足夠的活躍經(jīng)線來隱藏問題攤位)。
讓我們首先找出低SM占用率的主要原因。我們知道這個像素著色器有一個提前退出分支,如果分支被采用,通過輸出調(diào)試顏色,我們可以看到大多數(shù)像素正在提前退出。我們也從第6.2.2節(jié)知道,亂序像素著色器翹曲完成(與其啟動順序相比)可以限制SM占用。
為了驗證早退出分支實際上限制了占用率,讓我們做一下簡單地將它從像素著色器(ps_gather.hlsl)中移除的實驗:
#if0//如果速度太短,我們只顯示顏色紋理并退出如果(TempNX度量新的價值舊價值新舊GPU已用時間5.05毫秒0.70毫秒7.21x頂部SOL [0]SM:47.2%SM:40.7%1.16x頂部SOL [1]TEX:39.2%TEX:39.8%0.01XSM單元激活99.9%97.4%1.03X每個經(jīng)過周期的SM問題利用率47.2%40.7%1.16x每個活動周期的SM問題利用率47.2%41.8%1.13xSM入住率62.037.01.68xTEX命中率85.8%80.1%1.07倍L2命中率95.2%83.0%1.15倍 表1.刪除了早期退出分支的新度量標(biāo)準(zhǔn)。
我們發(fā)現(xiàn)新的工作負(fù)載仍然受到SM占用的限制,但占用率(62.0)達到了硬件限制(64.0) - 即使在這種最大占用率的情況下,我們也看到工作負(fù)載仍然受TEX頂級SOL單元的TEX延遲限制SM和TEX。
顯然,由于取消了提前退出,工作量減慢了7倍,但這是可以的,因為我們希望以這種方式研究其性能限制器。這實際上是我們經(jīng)常用來分析工作負(fù)載的一種方法,我們預(yù)計會出現(xiàn)多個性能問題:如果最初的問題太復(fù)雜,且SOL%s較低的根本原因不明確,則我們簡化問題(在此情況下,消除低占用率的預(yù)期根本原因),并對簡單問題重新進行分析,直到頂層SOL%s變好。這實際上是一個分而治之的性能調(diào)試方法。通過采取醫(yī)學(xué)比喻,我們正在消除一種病理學(xué),以便對其他病理學(xué)的分析更清楚并且沒有“相聲”。
注意:對于簡化的問題,性能優(yōu)化可能無法加速原始問題。但我們認(rèn)為,即使發(fā)生這種情況,對大多數(shù)情況下簡單問題的分析仍然非常值得,因為這不僅有助于我們驗證我們對性能問題的理解是否正確,而且還有助于重新設(shè)計用于避免GPU性能低效的渲染算法。
結(jié)論:
此工作負(fù)載中SM占用率較差的主要原因是像素著色器提前退出。將這個像素著色器移動到計算著色器可以緩解這個問題(扭曲完成比給定線程組中的其他處理器更早完成將仍然限制SM占用),但是也會增加一些開銷,用于通過無人機寫入指令寫出結(jié)果。
或者,使用第6.2.2節(jié)中描述的模板掩模方法在這種情況下也應(yīng)該有所幫助,因為它將使全屏像素著色器僅處理復(fù)雜像素,并且所有這些像素將按照啟動順序完成。
優(yōu)化1:使用R11G11B10F而不是RGBA16F
原始SDK示例應(yīng)用程序使用RGBA16F紋理格式存儲HDR顏色,這些顏色是由Motion Blur“Final Pass”過濾的顏色。
因為這個RGBA16F紋理的alpha通道從來沒有被這個應(yīng)用程序?qū)嶋H使用過,所以我們可以將其更改為更緊湊的R11G11B10F格式,從而生成在這種情況下看起來相同的輸出圖像。實現(xiàn)這種優(yōu)化只是main.cpp中的格式更改:
CreateTextureWithViews(設(shè)備,surface_desc->寬度,surface_desc->高度,#if0DXGI_FORMAT_R16G16B16A16_FLOAT,DXGI_FORMAT_R16G16B16A16_FLOAT,DXGI_FORMAT_R16G16B16A16_FLOAT,#其他DXGI_FORMAT_R11G11B10_FLOAT,DXGI_FORMAT_R11G11B10_FLOAT,DXGI_FORMAT_R11G11B10_FLOAT,#萬一這樣做可以通過提高TEX命中率來幫助減少顏色提取的TEX延遲:
度量新的價值舊值新舊GPU已用時間4.25毫秒5.05毫秒增加19%頂部SOL [0]SM:63.7%SM:47.2%1.35x頂部SOL [1]TEX:52.9%TEX:39.2%1.35xSM單元激活99.9%99.9%1.00倍每個經(jīng)過周期的SM問題利用率63.7%47.2%1.35x每個活動周期的SM問題利用率63.8%47.2%1.35xSM入住率62.862.01.01xTEX命中率94.2%85.8%1.10xL2命中率91.5%95.2%0.96x表2.顏色格式從RGBA16F降至R11G11B10F的新指標(biāo)。
優(yōu)化2:循環(huán)展開
現(xiàn)在,讓我們來看看這個全屏像素著色器的HLSL。它包含以下循環(huán),每個循環(huán)迭代有3個紋理提取,以及一個跳過循環(huán)體的動態(tài)分支,用于某個循環(huán)迭代索引:
for(inti=0;i使用以下命令行通過FXC運行此HLSL:
fxc/Tps_5_0/Ges/O3ps_gather.hlsl...在DXASM中產(chǎn)生以下控制流和紋理提?。?/span>
循環(huán)itofr5.w,r4.wger6.x,r5.w,cb0[21].zbreakc_nzr6.xieqr6.x,r3.x,r4.wif_nzr6.xmovr4.w,r3.w繼續(xù)endif...sample_l_indexable(texture2d)(float,float,float,float)r6.zw,r6.xyxx,t2.zwxy,s1,l(0.000000)... sample_l_indexable(texture2d)(float,float,float,float)r6.w,r6.xyxx,t1.yzwx,s1,l(0.000000)... sample_l_indexable(texture2d)(float,float,float,float)r6.xyz,r6.xyxx,t0.xyzw,s2,l(0.000000)madr5.xyz,r5.wwww,r6.xyzx,r5.xyzxiaddr4.w,r4.w,l(1)ENDLOOP我們知道這個工作量部分是TEX延遲有限。發(fā)生這種情況的原因是紋理提取和從屬數(shù)學(xué)指令之間沒有足夠的指令。為了讓我們的著色器編譯器更好地調(diào)度紋理指令,這個循環(huán)需要展開,所以我們的編譯器知道所有的紋理拾取都將被執(zhí)行,并且可以決定如何調(diào)度它們(可能將多個紋理拾取組合在一起)嘗試最佳用獨立的數(shù)學(xué)指令覆蓋紋理指令的延遲。
在這種情況下,循環(huán)迭代次數(shù)(“c_S”)必須在FXC編譯時已知,而原始著色器中c_S是常量緩沖區(qū)值時不是這種情況。
“c_s”常量存儲在一個常量緩沖區(qū)中,但由于該值不會逐幀變化,因此可以為不同的c_s常量生成此像素著色器的排列,或者僅使用#define對該值進行硬編碼, 喜歡這個:
#if0floatc_S;#其他#definec_S15floatc_S_unused;#萬一現(xiàn)在c_S在FXC編譯時已知,for()循環(huán)可以使用[unroll] HLSL關(guān)鍵字完全展開,如下所示:
[unroll]for(inti=0;i度量新的價值舊值新舊GPU已用時間3.44毫秒4.25毫秒24%的收益頂部SOL [0]SM:81.2%SM:63.7%1.27倍頂部SOL [1]TEX:81.2%TEX:52.9%1.53xSM單元激活99.9%99.9%1.00倍每個經(jīng)過周期的SM問題利用率74.4%63.7%1.17x每個活動周期的SM問題利用率74.5%63.8%1.17xSM入住率45.262.80.72xTEX命中率96.2%94.2%1.02XL2命中率85.6%91.5%0.94倍 表3.使用展開循環(huán)的新度量標(biāo)準(zhǔn)。
由于寄存器壓力增加,SM占用從每個活動周期的62.8到45.2有效彎曲下降:完全展開該循環(huán)導(dǎo)致更多的TEX指令同時執(zhí)行,這會消耗更多寄存器來存儲TEX結(jié)果。盡管如此,“每次活動周期的SM問題利用率”指標(biāo)為74.5%,接近80%,因此有更多的主動式經(jīng)紗可能會稍微提高性能,但不會超過工作負(fù)荷的10%。
總體而言,兩項優(yōu)化相結(jié)合,使工作負(fù)載的性能提高了47%(5.05至3.44毫秒)。并且,為了記錄,在退出早期退出分支后,這些優(yōu)化會使工作負(fù)載(0.75到0.62 ms)獲得21%的增益。
附錄:優(yōu)化Ray-Marching循環(huán)
如第6.2.2節(jié)所述(“減少SM問題 - 延遲延遲”),包含TEX指令的動態(tài)循環(huán)可能受到TEX指令的延遲以及沒有可以從相同的計劃調(diào)度的獨立指令的限制warp(沒有指令級并行性),并且SM中的活動warps數(shù)量不足以完全隱藏TEX延遲。
這種情況通常發(fā)生在光線漫游動態(tài)循環(huán)中,這些循環(huán)通常用于屏幕空間反射(SSR)著色器以及光線行進的體積照明。
在HLSL中,具有提前退出的典型SSR光線前進循環(huán)如下所示:
floatMinHitT=1.0;floatRayT=Jitter*Step+Step; [loop]for(inti=0;i通過部分展開循環(huán)2次并將紋理獲取指令背靠背放置在HLSL中,獨立紋理指令的批次可以并行執(zhí)行,并且第二次獲取的延遲可以部分由延遲隱藏的第一個。
假設(shè)NumSteps是2的倍數(shù),那么生成的HLSL看起來像這樣:
floatMinHitT=1.0;floatRayT=Jitter*Step+Step;[loop]for(inti=0;i通過在1607 Mhz的GTX 1080上以4K為單位的SSR測試應(yīng)用程序進行上述優(yōu)化,SSR工作負(fù)載所用的GPU時間從0.54 ms變?yōu)?.42 ms(工作負(fù)載加速29%)。通過進一步批量處理4個紋理,而不是2個,GPU時間下降到0.33 ms(工作負(fù)載加速64%:0.54 - > 0.33 ms /幀)。
-
NVIDIA
+關(guān)注
關(guān)注
14文章
4996瀏覽量
103214 -
gpu
+關(guān)注
關(guān)注
28文章
4744瀏覽量
129018
發(fā)布評論請先 登錄
相關(guān)推薦
評論