Unreal* Engine 4 VR應用的CPU性能優化和差異化:第一部分

作者:王文斕

虛擬現實(VR)能夠帶給用戶前所未有的沉浸體驗,但同時由於雙目渲染、低延遲、高分辨率、強制垂直同步(vsync)等特性使VR對CPU渲染線程和邏輯線程,以及GPU的計算壓力較大[1]。如何能有效分析VR應用的性能瓶頸,優化CPU線程提高工作的並行化程度,從而降低GPU等待時間提升利用率將成爲VR應用是否流暢、會否眩暈、沉浸感是否足夠的關鍵。Unreal* Engine 4 (UE4) 作爲目前VR開發者主要使用的兩大遊戲引擎之一,瞭解UE4的CPU線程結構和相關優化工具能夠幫助我們開發出更優質的VR應用。本文將集中介紹UE4的CPU性能分析和調試指令、線程結構、優化方法和工具、以及如何在UE4裏發揮閒置CPU核心的計算資源來增強VR內容的表現,爲不同配置的玩家提供相應的視聽表現和內容,優化VR的沉浸感。

本文已發表於《程序員》雜誌2017年08月期,如需轉載,可與《程序員》聯繫。

爲何要把PC VR遊戲優化到90fps

Asynchronous Timewarp(ATW),Asynchronous Spacewarp(ASW)和Asynchronous Reprojection等VR runtime提供的技術可以在VR應用出現掉幀的時候,以插幀的方式生成一張合成幀,等效降低延時。然而,這些並不是完美的解決方案,分別存在不同的限制:

ATW和Asynchronous Reprojection能夠補償頭部轉動(rotational movement)產生的 Motion-To-Photon(MTP)延遲,但如果頭部位置發生改變(positional movement)或者畫面中有運動對象,即使用上ATW和Asynchronous Reprojection,也無法降低MTP延遲; 另外ATW和Asynchronous Reprojection需要在GPU的drawcall之間插入,一旦某個drawcall時間太長(例如後處理)或者剩下來給ATW和Asynchronous Reprojection的時間不夠,都會導致插幀失敗。而ASW會在渲染跟不上的時候將幀率鎖定在45fps,讓一幀有22.2ms的時間做渲染,兩張渲染幀之間則以傳統圖像運動估算(motion estimation)的方式插入一張合成幀,如圖1所示。但合成幀中運動劇烈或者透明的部分會產生形變(例如圖1中紅圈框起來的部分),另外光照變化劇烈的時候也容易產生估算錯誤,導致持續用ASW插幀的時候用戶容易感覺到畫面抖動。這些VR runtime的技術在頻繁使用的情況下都不能夠很好解決掉幀問題,因此開發者還是應該保證VR應用在絕大部分情況下都能夠穩定跑在90fps,只有偶然的掉幀才依賴上述的插幀方法解決。圖片描述
圖 1.ASW插幀效果。

UE4性能調試指令簡介

用UE4開發的應用可以通過控制檯命令(console command)中的“stat”指令查詢各種實時性能數據[2-3]。其中“stat unit”指令可以看到一幀渲染總消耗時間(Frame)、渲染線程消耗時間(Draw)、邏輯線程消耗時間(Game)以及GPU消耗時間(GPU)。從中可以簡單看出哪部分是制約一幀渲染時間的主要原因,如圖2所示。結合“show”或“showflag”指令動態開關各種功能(features)來觀察分別對渲染時間的影響,找出影響性能的原因,期間可以用“pause”指令暫停邏輯線程來觀察。需要注意的是其中GPU消耗時間包括了GPU工作時間和GPU閒置時間,所以即使在“stat unit”下看到GPU花了最長的時間,也並不代表問題就出在GPU上,很有可能是因爲CPU瓶頸導致GPU大部分時間處於閒置狀態,拉長了GPU完成一幀渲染所需時間。因此還是需要結合其他工具,例如GPUView[4]來分析CPU和GPU的時間圖,從中找出實際瓶頸位置。
圖片描述
表 1.stat unit”統計數字。

另外,因爲VR是強制開啓垂直同步的,所以只要一幀的渲染時間超過11.1ms,即使只超過0.1ms,也會導致一幀需要花兩個完整的垂直同步週期完成,使得VR應用很容易因爲場景稍微改變而出現性能大降的情形。這時候可以用“–emulatestereo”指令,同時把分辨率(resolution)設爲2160x1200,屏幕百分比(screenpercentage)設爲140,就可以在沒有接VR頭顯及關閉垂直同步的情況下分析性能。

而渲染線程相關的性能數據可以通過“stat scenerendering”來看,包括繪製調用(drawcall)數目、可見性剔除(visibility culling)時長、光照處理時間等。其中可見性剔除又可以通過“stat initviews”指令進一步瞭解和分柝各部分的處理時長,包括視錐剔除(frustum culling)、預計算遮擋剔除(precomputed visibility culling)和動態遮擋剔除(dynamic occlusion culling)等,用以判斷各剔除的效率; 輸入“stat sceneupdate”指令查看更新世界場景例如添加、更新和移除燈光所花費的時間。另外,也可以通過“stat dumphitches”指令,指定一幀的渲染時間超過t.HitchThreshold時把渲染幀信息寫進日誌。

如果要使遊戲效果能夠適配不同等級的PC,那麼“stat physics”,“stat anim”和“stat particles”會是三個經常用到跟CPU性能相關的指令,分別對應到物理計算時間(布料模擬,破壞效果等)、蒙皮網格(skin meshing)計算時間和CPU粒子計算時間。由於這三個計算在UE4裏都能夠分到工作線程作並行處理,因此對這些部分進行擴展能夠把VR應用有效適配到不同等級的硬件,使VR體驗以及效果能夠隨着CPU的核數增加而增強。

另外,可以直接輸入控制檯命令“stat startfile”和“stat stopfile”採集一段實時運行的數據,然後用UE4 Session Frontend裏的Stats Viewer查看運行期間各時間段CPU線程的利用率和調用堆棧(call stack),尋找CPU熱點並進行相應的優化,如圖3所示,功能類似Windows* Assessment and Deployment Kit(ADK)裏的Windows* Performance Analyzer(WPA)。


查看全文


瞭解更多相關內容,請關注CSDN英特爾開發專區

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章