chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Vulkan在移動端渲染中的帶寬與同步詳解

冬至子 ? 來源:內(nèi)核工匠 ? 作者:ningfeili ? 2023-12-01 16:45 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1.移動端GPU架構(gòu)

Immediate Mode Rendering Architecture(IMR)

image.png

早先PC端的GPU大多數(shù)采用的是IMR的架構(gòu)。IMR架構(gòu)的大體流程如圖所示,值得注意的是對于每個像素,經(jīng)過數(shù)次的color/depth的讀寫,最終繪制到framebuffer上。這當(dāng)中的每一次讀寫,都是直接與內(nèi)存交互。所以,頻繁讀寫內(nèi)存,會消耗大量的帶寬,這個過程會大量發(fā)熱。對PC來說,為了更高的畫質(zhì)和幀率,可以用更好的風(fēng)扇和散熱從外部解決發(fā)熱問題,但是對于空間十分有限的手機來說,肯定不可能去加裝散熱了。

Tile-Based Rendering Architecture(TBR)

所以為了解決帶寬引起的發(fā)熱問題,現(xiàn)在的手機GPU普遍使用的是tiled-based架構(gòu),Adreno/Mali/PowerVR的GPU在這個基礎(chǔ)上有自家獨有的優(yōu)化,比如PowerVR的TBDR架構(gòu)中的HSR,可以完全消滅不透明物體渲染時的overdraw,這里就不展開討論了。

不過它們的核心思想是一致的,都是為GPU開辟了一塊on-chip memory,這塊on-chip memory的特點就是相比于與內(nèi)存的交互,GPU讀寫它的開銷非常小。

Tile-based rendering將一個完整的framebuffer分為若干個tile,每個tile的內(nèi)容完全繪制完畢之前,GPU只讀寫on-chip memory,一塊tile完全渲染完畢之后才會將on-chip memory中的內(nèi)容一次性寫入內(nèi)存,下圖描述了整體的繪制流程。

image.png

這樣,原本繪制每個像素都需要直接讀寫內(nèi)存,現(xiàn)在改為全部讀寫開銷極低的on-chip memory,從而節(jié)約了帶寬,降低了功耗。

2.為什么用Vulkan?

這也是在移動端渲染開發(fā)必然要考慮的問題,要求引擎技術(shù)團隊對自己的項需求和Vulkan API,以及相關(guān)手機硬件特性都有非常清晰的認知。Vulkan API主要有以下幾點特殊的優(yōu)勢:

  1. 它的驅(qū)動更薄。Vulkan更貼近底層,驅(qū)動不會像GLES一樣,進行大量的猜測和判斷,所以用得好可以顯著降低CPU的負載;
  2. Vulkan提供顯式的同步和帶寬控制指令,有效而正確地使用這些指令,可以提升GPU運行效率和降低GPU功耗。
  3. Vulkan 刻錄并提交commandbuffer的架構(gòu),更好地支持了多線程渲染。例如Unity PC端實現(xiàn)了用secondary commandbuffer多線程同時渲染同一場景中的物體,UE也利用Vulkan的特性,從渲染線程中抽離出了RHI線程,平均了多核負載,提升了多核效率。
  4. 因為Vulkan標(biāo)準(zhǔn)較新,且受到重視,所以在Vulkan標(biāo)準(zhǔn)定制時,直接包含了很多最新的硬件特性的使用方法。

所以在合理調(diào)度的情況下,Vulkan可以享受驅(qū)動薄和多線程帶來的CPU收益。而GPU端,在充分了解硬件架構(gòu)和各個驅(qū)動的特點的情況下,手動控制同步和帶寬可以有效提升游戲性能。但是,往往一些項目花了非常多的時間和精力去優(yōu)化渲染算法,改善渲染流程,或者添加自定義渲染管線,可僅僅是因為對某個硬件特性的不了解,或者用錯了某個API,導(dǎo)致性能下降非常嚴(yán)重或者導(dǎo)致優(yōu)化了的算法反而是負提升,甚至包括早期的Unity、Unreal默認移動端的渲染管線,在這塊都或多或少有些不足。

3.游戲中的帶寬與功耗

先看一個非常簡單的例子。

image.png

上圖是用Unity的rendering commandbuffer實現(xiàn)的一個自定義后處理的渲染流程。當(dāng)切換rendertarget的時候,如果我們只是使用了默認的接口去設(shè)置RT,傳遞到底層,可以看到Vulkan renderpass的load action是load,也就是保留前面的渲染結(jié)果。

而當(dāng)我們使用下面這個接口顯示地設(shè)定了rendertarget的loadaction,使Vulkan的load action變?yōu)閐ontcare,可以看到GPU bound的情況下,幀率提升了1幀多。

image.png

這就是因為,當(dāng)我們load這個rendertarget的時候,在Tile-base架構(gòu)上,rendertarget從內(nèi)存中被加載到on-chip memory上,所以產(chǎn)生了額外的開銷。而如果我們顯式地設(shè)置了dontcare,就減少了這次加載的時間和帶寬,在GPU bound的情況下,性能的提升直接體現(xiàn)在了幀率上。

Tile-based Rendering在延遲渲染中的應(yīng)用

image.png

傳統(tǒng)延遲渲染的方式,Gbuffer渲染完畢后,寫入內(nèi)存,然后lighting階段再sample gbuffers。而因為在lighting階段每個像素需要的是自己像素位置上的gbuffer信息,所以我們完全可以利用subpass,將gbuffer存放在on-chip memory中,后續(xù)lighting階段直接從on-chip memory里去讀取。省去了先存內(nèi)存,再sample的兩次帶寬消耗。

下面是一個延遲渲染的demo,左邊是sample的方式,右邊是則是subpass的方式:

image.png

兩種情況下,lighting的算法,分辨率,燈的數(shù)量,fps包括GPU頻率都是固定不變的。唯一的區(qū)別就是是否與內(nèi)存交互,左邊是采樣內(nèi)存中存下來的Gbuffer;右邊則完全不與內(nèi)存交互,直接寫入和讀取on-chip memory。

image.png

測試結(jié)果可以看到,shader的計算量是一樣的,但是內(nèi)存頻率和帶寬都是subpass方案有很大提升,這里讀寫帶寬一共減少了4.9Gb/s,內(nèi)存頻率也有所降低。

image.png

在幀率、GPU使用率和頻率均沒有差別的情況下,純因為帶寬的減少,產(chǎn)生了567mW的功率差,GPU平均溫度也降低了5度。

image.png

這里有一個大致的參考,內(nèi)存帶寬所產(chǎn)生的功耗幾乎與GPU的功耗持平,,每消耗1GB的內(nèi)存帶寬,大約會產(chǎn)生120mW的功耗,這也和之前5GB,567mW的測試結(jié)果吻合。

不僅僅是延遲渲染,只要渲染流程中想讀取當(dāng)前像素位置的歷史顏色、深度,都可以用subpass。比如decal,某些粒子效果的半透明渲染、MSAA抗鋸齒等等,合理利用subpass,在帶寬上能得到可觀的收益。

當(dāng)然,tile-based架構(gòu)還是有一些缺點的:

比如tiling階段需要將vs全部計算完畢,并且所有的varying要回存內(nèi)存,所以相比于IMR,除了共有的fetch geometry data的開銷,Tiling階段也有額外的延遲和帶寬消耗。

image.png

所以vertex data的組織也是非常重要的。比如下圖這個自定義的vertex data,aColor將最終傳給fragment shader用作自定義的渲染,

image.png

注意到每個數(shù)據(jù)都是有效數(shù)字只有1位的整數(shù),卻用了32位的格式去存儲。在模型復(fù)雜,頂點較多的情況下,這也是一筆不小的開銷。實際上16位,甚至8位的格式就夠了。所以在知曉自己項目每個頂點數(shù)據(jù)的用途的情況下,我們應(yīng)當(dāng)使用盡量小的格式。

Index-Driven Vertex Shading(IDVS)

下圖是ARM上為了減少fetch geometry data的帶寬所做的優(yōu)化,嚴(yán)格意義上它不能算是專門為TBR架構(gòu)而設(shè)計的優(yōu)化,但它的收益確實很大。

image.png

IDVS的思路就是vs中只先做position相關(guān)的計算,等做完剔除之后,才會去fetch其他attribute的數(shù)據(jù),做varying相關(guān)的計算。但是這個優(yōu)化要求開發(fā)者將position和其他的attribute分buffer存放,這樣GPU才能單獨fetch。

現(xiàn)在市面上絕大多數(shù)的手游都是左邊的這種情況,所有vertex data存在了同一個vkbuffer中;右邊則是推薦的做法,一個vkbuffer僅存position data,剩下的varying存在另一個vkbuffer中,在某些vs較重的情況下,兩者的功耗差距超過了30%。所以如果頂點數(shù)據(jù)復(fù)雜,我們還是值得去拆分一下vertex data的。

4.Vulkan中的同步

Vulkan同步中一個非常重要的元素就是pipeline barriers,只要有項目修改了引擎的原生管線,就一定會涉及到pipeline barrier的修改,而實際看下來幾乎所有的項目都有一些使用不恰當(dāng)?shù)牡胤健2⑶?,如果項目開發(fā)周期比較長,使用的是較早版本Unity、Unreal引擎,那么原生代碼也或多或少有一些使用不當(dāng)?shù)牡胤健?/p>

以下三點都是Vulkan spec上面提到的pipeline barrier的作用。

第一,它可以控制執(zhí)行順序,GPU真正執(zhí)行指令時,并不一定是按照我們提交指令的順序去執(zhí)行的,所以在指令之間添加一個pipeline barrier,可以保證barrier之前的指令先于barrier之后的指令執(zhí)行。

只保證指令開始的順序,在并行的情況下,并不能控制指令結(jié)束的順序,牽涉到內(nèi)存修改的情況下就會出現(xiàn)問題。

第二,pipeline barrier還保證了指令間內(nèi)存的依賴關(guān)系,這個后面會詳細解讀。

第三點image的layout轉(zhuǎn)換其實同樣重要,有興趣的讀者可以查閱相關(guān)資料。

Hazards

因為實際情況要復(fù)雜得多,這里我們把讀寫模型簡化成GPU core - cache–內(nèi)存三個部分:

image.png

寫數(shù)據(jù)時,GPU core完成對cache的修改后要flush cache,將其中的數(shù)據(jù)拷貝到內(nèi)存中,這個過程我們稱之為make memory available。

而GPU core讀取數(shù)據(jù)時,要先invalidate cache,將內(nèi)存中的數(shù)據(jù)加載到cache中,這個過程,我們稱之為make memory visible。

了解了這個簡化模型以后,來看內(nèi)存讀寫的三個hazards:寫后讀、寫后寫、讀后寫。

如果不做同步,比如說寫后讀,很可能讀取指令執(zhí)行時,前面的寫命令還沒來得及修改內(nèi)存,從而導(dǎo)致渲染錯誤,這類情況就是需要通過同步指令去避免的。

Pipline Barrier 處理WAR、RAW、WAW的具體流程

三個問題當(dāng)中最好解決的是讀后寫,對于它來說,只要通過pipeline barrier限制了指令執(zhí)行順序,就能保證數(shù)據(jù)讀取的正確性。因為讀取指令先執(zhí)行,那么數(shù)據(jù)就已經(jīng)被加載到了cache中,即使最壞的情況,后面的寫入操作立刻完成,它修改的也僅僅是內(nèi)存中的內(nèi)容,無法影響到我們正在讀取的已經(jīng)被加載到cache中的數(shù)據(jù)。

接下來我們來看其他兩個稍微復(fù)雜一點的同步。

Pipeline stage mask和access mask決定了這個pipeline barrier是對哪段內(nèi)存生效。那么如果對于同一段內(nèi)存進行先寫后讀,讀取操作一定要在所有數(shù)據(jù)都寫入內(nèi)存之后才能進行。

image.png

所以,在pipeline barrier的保護下,整個同步流程如右上所示:

首先,讀取指令會被block住,等待寫指令執(zhí)行完畢;srcAccessMask意味著將這段內(nèi)存make available,保證data寫入內(nèi)存完畢。dstAccessMask意味著將這段內(nèi)存make visible,也就是保證剛才被寫入內(nèi)存的data成功加載到cache中。

最后,執(zhí)行讀取指令。這樣,整個內(nèi)存同步就完成了。

寫后寫也是差不多的原理,先阻塞第二次寫操作,等待第一次寫操作完成,且data已經(jīng)flush到了內(nèi)存中,再執(zhí)行后一次的寫操作。

image.png

上面是一個典型的寫后讀的同步例子,這是一個用采樣方式讀取Gbuffer的延遲渲染demo,模擬是游戲中最常見的一種流程,就是先渲染一張RT,然后后續(xù)的某個fragment shader采樣這個RT的結(jié)果,除了延遲渲染,常見的還有shadowmap,sss,一些實時的風(fēng)場,腳印的前置流程等等。

右邊是完全正確的寫法,先block住lighting階段的fs,然后把之前Gbuffer階段color output stage的color attachment寫入的這段內(nèi)存make available,然后再make visible同一段要被shader讀取的內(nèi)存,再unblock fs,這樣lighting階段的fs就正確讀取到了Gbuffer。

左邊唯一的不同,是把本應(yīng)等待的fragment階段改成了vertex,這樣就導(dǎo)致GPU會在vertex shading階段提前block住流水線。

這個問題非常隱蔽,首先Vulkan的validation layer不會報錯,因為它只是效率低,而不是一個錯誤。如果粗略地去測試alu,讀寫帶寬,渲染時間,可以看到這些數(shù)據(jù)在圖上的測試結(jié)果幾乎沒有區(qū)別。所以這個問題很容易就被忽略過去了。

測試分析工具的使用

各個Soc廠商都提供了自家GPU的分析測試工具,例如 Mali芯片的Mali streamline,PowerVR的芯片的PVRTune,高通的snapdragon profiler。在這個例子中,我們用的手機是Mali的GPU,所以用Mali的測試工具進行分析:

image.png

如上圖,計算量,讀寫帶寬,都沒有差別,唯一有變化的是這個External Bus Read Latency和External Bus Stall。

image.png

具體來看,內(nèi)存總線讀取數(shù)據(jù)的阻塞周期有6倍的差距,這就是由于我們的同步指令讓該等待的stage提早到了vertex shading階段。但是由于GPU頻率足夠高,場景也不夠復(fù)雜,沒有達到GPU bound,這些延遲并沒有高到足以影響幀率的地步。

現(xiàn)在,讓我們?nèi)藶榈叵拗艷PU頻率,模擬GPU bound的情形,這時內(nèi)存總線讀寫延遲無法被覆蓋,問題就暴露出來了。

image.png

可以看到,Bus Stall對幀率的影響還是很明顯的,frametime相差了3毫秒,也就是8幀如果沒有進行足夠深入的測試,就很容會忽略掉這個問題,隨著項目向后期推進,渲染壓力逐漸變大,當(dāng)問題暴露出來的時候,可能已經(jīng)無法找到最初的原因了。

綜上,同步問題非常重要,我們要完全理解core-cache-memory這個模型,清楚地知道管線遇到的是哪種hazard,正確地使用pipeline barrier,從而充分發(fā)揮手動控制同步帶來的性能收益。

其他同步指令

當(dāng)然Vulkan中還有很多其他的同步指令,例如subpass dependency,和barrier的用法幾乎一樣,但是只能同步renderpass內(nèi)attachment相關(guān)的內(nèi)存。Semaphore用于隊列之間的同步,fence用于同步GPU和CPU,Event現(xiàn)在手游上用的比較少,目前除了一兩款游戲自己對引擎進行了改動,只有unreal最新的版本在mobile shading renderer的occlusion query部分使用了它。

5.總結(jié)

本文首先介紹了移動端渲染架構(gòu)及其特點,接著闡述了Vulkan API的優(yōu)勢,再結(jié)合實際測試結(jié)果分析了Tile-based rendering的優(yōu)缺點,最后重點介紹了Vulkan的顯式同步控制,結(jié)合具體場景和實測數(shù)據(jù),給出了優(yōu)化方案并分析了根因。

希望讀者可以通過本文更加深入地了解Vulkan API以及移動端渲染架構(gòu),結(jié)合具體的開發(fā)場景,合理利用測試分析工具,改善移動端渲染中的功耗、帶寬和同步問題。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • RAW
    RAW
    +關(guān)注

    關(guān)注

    0

    文章

    21

    瀏覽量

    4205
  • cache技術(shù)
    +關(guān)注

    關(guān)注

    0

    文章

    41

    瀏覽量

    1360
  • Vulkan
    +關(guān)注

    關(guān)注

    0

    文章

    31

    瀏覽量

    6122
  • GPU芯片
    +關(guān)注

    關(guān)注

    1

    文章

    307

    瀏覽量

    6506
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    Vulkan同步機制和圖形轉(zhuǎn)換的風(fēng)險

    Vulkan同步機制和圖形-計算-圖形轉(zhuǎn)換的風(fēng)險(一)
    發(fā)表于 01-21 06:17

    Vulkan如何使用barrier

      本篇文章,我們將提到Vulkan 圖形處理過程夾雜計算任務(wù)時遇到的各式問題。為更準(zhǔn)確地了解我們的話題,可查看文章第一部分?! 〉谝徊糠指攀隽?/div>
    發(fā)表于 01-29 06:55

    一文詳解渲染管線

    渲染管線簡單梳理
    發(fā)表于 02-03 07:13

    HarmonyOS/OpenHarmony應(yīng)用開發(fā)-ArkTS語言渲染控制if/else條件渲染

    ; { this.count--; }) } } } if語句的每個分支都包含一個構(gòu)建函數(shù)。此類構(gòu)建函數(shù)必須創(chuàng)建一個或多個子組件。初始渲染時,if語句會執(zhí)行構(gòu)建函數(shù),并將生成的子組件添加到其父組件
    發(fā)表于 08-21 14:29

    分布式塔臺模擬機同步渲染算法的研究

    基于分布式的塔臺模擬機,難點是多機渲染同步問題。文中提出一種使用雙網(wǎng)結(jié)構(gòu)的塔臺模擬機體系結(jié)構(gòu),并從渲染空間同步、動態(tài)數(shù)據(jù)
    發(fā)表于 12-14 15:11 ?16次下載

    PTN 時間同步方案移動網(wǎng)絡(luò)的應(yīng)用

    PTN 時間同步方案移動網(wǎng)絡(luò)的應(yīng)用 移動技術(shù)從 2G 向3G、到LTE 發(fā)展推動著移動傳送
    發(fā)表于 11-02 12:02 ?2131次閱讀
    PTN 時間<b class='flag-5'>同步</b>方案<b class='flag-5'>在</b><b class='flag-5'>移動</b>網(wǎng)絡(luò)<b class='flag-5'>中</b>的應(yīng)用

    更新Vulkan工具:Adreno SDK 和 Snapdragon Profiler

    Technologies Inc. 和 Epic Games公司工程師還利用Protostar展示了Vulkan移動領(lǐng)域的威力,及Vulkan API在內(nèi)置Adreno?GPU 5
    發(fā)表于 09-18 19:09 ?1493次閱讀

    暢快開黑 一加6T開通王者榮耀Vulkan模式

    更加極致的游戲體驗。 圖:一加6T現(xiàn)已開通Vulkan模式 Vulkan是Khronos 標(biāo)準(zhǔn)組織退出的新一代圖形處理接口(API)標(biāo)準(zhǔn),其充分考慮到移動平臺多核CPU和GPU協(xié)同處理任務(wù)的特點,降低功耗的同時還能進一步提高
    的頭像 發(fā)表于 11-09 09:30 ?2424次閱讀

    Vulkan編程接口的特征

    Vulkan 簡介 Vulkan是一個用于圖形和計算設(shè)備的編程接口。Vulkan設(shè)備通常由一個處理器和一定數(shù)量的固定功能硬件模塊組成,用于加速圖形和計算操作。通常,設(shè)備的處理器是高度
    的頭像 發(fā)表于 03-15 17:17 ?2691次閱讀

    FFmpeg將初步支持Vulkan

    近期 Vulkan 勢頭不小,游戲引擎 Godot 計劃年中發(fā)布的 4.0 大版本中將支持 Vulkan,Raspberry Pi 也即將迎來 Vulkan 的支持?,F(xiàn)在我們還可以看到 FFmpeg 也將支持
    的頭像 發(fā)表于 03-16 09:38 ?2836次閱讀

    高通驍龍865移動平臺首次將“游級正向渲染”帶入安卓平臺

    高通驍龍865移動平臺首次將“游級正向渲染”帶入安卓平臺。作為新一代 Snapdragon Elite Gaming的特性之一,游級正向渲染
    的頭像 發(fā)表于 05-29 10:38 ?3419次閱讀

    Vulkan API 基本類型介紹

    Vulkan 基本類型,Vulkan 開發(fā)需要設(shè)計的類型非常多,整理其基本類型如下,主要包含設(shè)備、隊列、命令緩沖、隊列家族、渲染通,管線等……
    的頭像 發(fā)表于 02-12 16:19 ?2865次閱讀

    Vulkan API 基本類型 小結(jié)

    Vulkan 基本類型,Vulkan 開發(fā)需要設(shè)計的類型非常多,整理其基本類型如下,主要包含設(shè)備、隊列、命令緩沖、隊列家族、渲染通,管線等……
    發(fā)表于 02-23 06:02 ?5次下載
    <b class='flag-5'>Vulkan</b> API 基本類型 小結(jié)

    BEM移動開發(fā)的應(yīng)用案例

    BEM(Block Element Modifier)移動開發(fā)的應(yīng)用案例非常廣泛,它作為一種前端開發(fā)的命名規(guī)范和架構(gòu)方法,旨在提高代
    的頭像 發(fā)表于 02-12 17:13 ?1005次閱讀

    基于Vulkan側(cè)AI運算

    本期內(nèi)容由AI Model SIG提供,介紹了開源鴻蒙,利用圖形接口Vulkan的計算著色器能力,側(cè)部署大模型的的整體思路和實踐分享
    的頭像 發(fā)表于 09-10 17:19 ?1298次閱讀
    基于<b class='flag-5'>Vulkan</b>的<b class='flag-5'>端</b>側(cè)AI運算