在關(guān)于單一緩沖帶渲染的文章中,我談到了通過縮短圖形管線長(zhǎng)度來減少延遲。隨后,我又闡述了一種通過將變形轉(zhuǎn)換移出片段著色器而加速桶形失真渲染的方法。這兩種方法都可以增加吞吐量,因此有助于減少VR使用的延遲。當(dāng)然,還有其他技巧來進(jìn)一步加快VR內(nèi)容的創(chuàng)建。例如,一個(gè)有趣的方法是將變形轉(zhuǎn)換移到內(nèi)容生成步驟中,使得第二次顯示渲染基本過時(shí)。雖然這是個(gè)不錯(cuò)的方案,但它需要得到VR應(yīng)用程序的直接支持,因此在通用虛擬框架中是不可用的。
另一個(gè)技巧是最終的內(nèi)容呈現(xiàn)給用戶之前進(jìn)行一次投影,并分離內(nèi)容生成和VR后處理。正如單緩沖地帶渲染一樣,恰當(dāng)?shù)臅r(shí)機(jī)非常重要。
在本文中,我將闡述當(dāng)在VR中使用這些先進(jìn)的技術(shù)時(shí),為何GPU支持細(xì)密度優(yōu)先是必不可少的。
確定CPU
在談?wù)揋PU之前,先談?wù)凜PU和Linux調(diào)度。
我們需要將幀速率保持在最低60 fps,以維持VR環(huán)境中的“存在”感。高端桌面PC的VR平臺(tái)則要求更高。而比高分辨率內(nèi)容等有一個(gè)更加平穩(wěn)的幀速率則更為重要。開發(fā)人員應(yīng)該不斷調(diào)整內(nèi)容以實(shí)現(xiàn)這些幀速率。然而,即使他們這樣做,仍可能會(huì)有內(nèi)容創(chuàng)建跟不上步伐而降至60 fps以下的情況。切記,Android / Linux是一個(gè)多進(jìn)程的操作系統(tǒng),因此無法保證具體進(jìn)程/線程的實(shí)時(shí)行為。這個(gè)過程可能在任何時(shí)候被打斷,且將這個(gè)過程從一個(gè)CPU轉(zhuǎn)移到另一個(gè)CPU是一項(xiàng)消耗成本的操作。這是因?yàn)槊總€(gè)CPU會(huì)有一些緩存,而轉(zhuǎn)移時(shí)緩存會(huì)變得無效。
克服這個(gè)問題的一個(gè)方法是將一個(gè)特定的線程定位在一個(gè)特定的CPU中。使用sched_setaffinity可以大大提高VR應(yīng)用程序的調(diào)度行為。此外,Android已經(jīng)開始使用CPU集來分配特定的進(jìn)程(比如后臺(tái)服務(wù)),用于篩選CPU組。甚至有一個(gè)涵括了專有CPU的高端APP CPU集僅供前端應(yīng)用程序使用。


Linux調(diào)度的系統(tǒng)調(diào)用跟蹤提供器(Systrace)可以進(jìn)行CPU定位。將內(nèi)容創(chuàng)建線程固定在CPU 2中,VR后處理線程固定在CPU 3中。
將一個(gè)重要的線程固定在一個(gè)特定的CPU中甚至使其可專門訪問CPU將是獲得一致渲染體驗(yàn)的重要步驟。現(xiàn)在,SoC通常由4個(gè)或更多CPU組成,因此便不再存在大的障礙了。
然而,即使有了這些預(yù)防措施也不能確保實(shí)時(shí)行為。
GPU優(yōu)先
VR里一個(gè)較為先進(jìn)的技術(shù)是異步時(shí)間彎曲。在VR中, Oculus第一次實(shí)現(xiàn)了異步時(shí)間彎曲。使用其主要為實(shí)現(xiàn)兩個(gè)目標(biāo):
1.減少延遲
2.提高幀速率
如何實(shí)現(xiàn)這些目標(biāo)我不做過多闡述,您可以在我寫的有關(guān)Oculus的文章或相關(guān)視頻中獲取詳細(xì)資訊。關(guān)鍵在于在垂直同步之前的一段極短的時(shí)間內(nèi),算法要等待最后的渲染正式啟動(dòng)。這樣便可以再次查詢到傳感器,從而減少移動(dòng)時(shí)間延遲。最后的渲染有一個(gè)固定的工作負(fù)載,且SoC供應(yīng)商可以估計(jì)完成這個(gè)任務(wù)所需的正常時(shí)間。
此外,為提高幀速率,可以通過使用兩個(gè)不同的獨(dú)立運(yùn)作的線程,將內(nèi)容創(chuàng)建與VR后處理進(jìn)行分解。
GPU優(yōu)先適合的位置在哪?就像我所說,GPU只有一點(diǎn)時(shí)間來處理VR后處理渲染。SoC供應(yīng)商總是選擇最小的可能值來獲取傳感器最晚讀取的信息。問題在于與此同時(shí) (異步)內(nèi)容渲染(或系統(tǒng)中的其他內(nèi)容)也提交了其他工作。我們?nèi)绾伪WC重要的后處理渲染在目標(biāo)時(shí)間內(nèi)完成?
內(nèi)容優(yōu)先
首先,我們需要了解的是現(xiàn)代GPU有一個(gè)調(diào)度器用于分配多個(gè)渲染任務(wù)至一個(gè)或少量的硬件單元。調(diào)度器需要考慮運(yùn)行任務(wù)是否準(zhǔn)備就緒,未完成的任務(wù)是否具有相關(guān)性,從而另一個(gè)任務(wù)可以同時(shí)運(yùn)行。此外,調(diào)度器也能夠中斷正在運(yùn)行的任務(wù)而切換至高優(yōu)先級(jí)的任務(wù)。PowerVR Rogue硬件架構(gòu)的設(shè)計(jì)旨在進(jìn)入非常細(xì)的粒度層次時(shí)進(jìn)行中斷。這就允許在完成一個(gè)貼圖和開啟下一個(gè)貼圖過程之間進(jìn)行中斷。例如,貼圖像素為32×32允許在處理全屏渲染時(shí)進(jìn)行多次中斷。
為使這種先進(jìn)的GPU調(diào)度控制機(jī)制適用于OpenGL ES(或計(jì)算)開發(fā)人員,Imagination Technologies早在2009年就推出了EGL_IMG_context_priority擴(kuò)展。同年,該擴(kuò)展獲得了Khronos的批準(zhǔn)。它定義了三個(gè)優(yōu)先層以區(qū)分單個(gè)工作負(fù)載之間的需求。在我們的VR使用中,顯然我們選擇了EGL_CONTEXT_PRIORITY_HIGH_IMG用于后處理線程,而EGL_CONTEXT_PRIORITY_MEDIUM_IMG用于內(nèi)容渲染(默認(rèn))。
在系統(tǒng)調(diào)用跟蹤提供器(systrace)中可以看到效果:

Systrace強(qiáng)調(diào)GPU優(yōu)先
我人為地增加了內(nèi)容渲染的工作負(fù)載,想看看它如何影響后處理渲染任務(wù)。可以看到,內(nèi)容創(chuàng)建線程大約每32ms提交一次渲染。VR后處理線程每16.7ms提交一次渲染以保持穩(wěn)定的60 fps幀率。上圖綠色的內(nèi)容渲染任務(wù)被藍(lán)色的后處理任務(wù)打斷了,“GPU:3D”行進(jìn)行了標(biāo)注。綠色的“內(nèi)容創(chuàng)建任務(wù)2”三次被多個(gè)藍(lán)色打斷。這便可以確保藍(lán)色后處理任務(wù)能及時(shí)完成目標(biāo)幀率。
總結(jié)
細(xì)粒度GPU優(yōu)先使單獨(dú)的緩沖帶渲染或異步時(shí)間彎曲等技術(shù)成為了可能。它有助于在創(chuàng)造豐富的內(nèi)容和VR后處理之間,甚至在CPU或GPU不能及時(shí)跟上任務(wù)時(shí)進(jìn)行一個(gè)平衡。顯然,可能有其他GPU優(yōu)先的案例,且開發(fā)者可以自由地利用EGL_IMG_context_priority擴(kuò)展自己的應(yīng)用程序。便攜式設(shè)備對(duì)VR任務(wù)的要求很高,開發(fā)人員也應(yīng)該留意CPU調(diào)度并利用所有可用的分析工具。
英文鏈接:
https://imgtec.com/blog/importance-fine-grained-gpu-preemption-support-vr/
相關(guān)閱讀:
1、移動(dòng)VR設(shè)備中通過采用單緩沖器條帶式渲染來降低延
2、在移動(dòng)VR中加速修正GPU桶形失真
3、虛擬現(xiàn)實(shí)中的“存在感”及PowerVR GPU發(fā)揮的作用
電子發(fā)燒友App









評(píng)論