2020年7月18日 星期六

Mobile 渲染效能分析 (1)

  • 前言
本系列著重在 mobile 的效能優化上,會分成硬體和軟體兩個角度去分析探討效能優化。

本篇探討 mobile 硬體架構,並以 Imagination Technologies 的 PowerVR 晶片為範例,

說明如何有效應用硬體資源,達到效能的最大化。


  • Tile-Base Rendering

在談到 mobile 效能,就必須要說明 Tile-Base Rendering (之後簡稱 TBR)。

我們知道 GPU 上的 on-chip memory (i.e. SRAM, 或 L1 L2 cache) 很小,

對於一個螢幕解析度,假設是 1920 x 1080,這樣大的 Frame Buffer來說,是絕對不夠用的。

因此會使用一個存取速度慢但有比較大的記憶空間(i.e. DRAM)來儲存。

對於 DRAM 的存取,就是效能的最大瓶頸,

不但讀寫速度慢,也需要花費大量的電力去操作。(這也是裝置發熱耗電的原因)

mobile 為了延長使用時間,必須減少對 DRAM 的存取,降低裝置發熱耗電的損失。

因此在硬體上,將 Frame Buffer 分成很多個 tile (區塊),

這些 tile 小到可以被 SRAM 儲存,GPU 可以直接對這個 Tile 做讀寫,

等不再使用後,在傳送到 DRAM 去儲存。

試想,一個 1920 x 1080 的 Frame Buffer,

要填滿整個畫面,會需要對 DRAM 做 1920 x 1080 次的存取。

假設每個 Tile 10 x 10,先寫入 Tile 在回傳 DRAM 的話,

要填滿整個畫面,只需要做 192 x 108 次的存取。

實際上, Tile 的大小會根據裝置設備來決定。

但可以知道的是,這種做法可以確實地降低對 DRAM 的存取。(註1)

這種將 Frame Buffer 分割成數個 Tile 分批進行處理的作法,

就叫做 Tiled-Base Render。

Tile-Base Render 示意圖


  • Tile-Base Deffered Rendering

TBR 架構看似完美,但實際上仍有問題存在。

假設 畫面中,有 Sphere 和 Cube 要被渲染,渲染順序是先 Sphere 之後 Cube。

首先 Sphere 經過 Tiler(註2)計算後,被分配在 Tile A 之內。

根據上面所述 TBR 流程,這時 GPU 需要先複製 Tile A 到 Tile Buffer,

渲染之後寫回 Frame Buffer 儲存。

但渲染下一個 Cube 時,經過 Tiler 計算時發現也是被分配到 Tile A 內。

這時悲劇就發生了,GPU 必須要重複渲染 Sphere 時一樣的動作,

將 Tile A 再一次複製到 Tile Buffer 內,最後在寫回 Frame Buffer。


為了避免上述的悲劇,必須要確定寫入每個 Tile 的資料都已經結束了,

(以上例來說,Sphere 和 Cube 都計算完了) 才能覆蓋回 Frame Biffer 裡面。

這種將覆蓋回去的動作延遲(Defered)到最後的 TBR 流程,

稱作 Tile-Base Deffered Rendering (之後簡稱 TBDR)。


在實作上,通常會在 System memory 裡,分配一個空間( Frame Data)

去儲存每個 Tile 裡面經過 Vertex Shader 計算後的節點資料,

當 Tile 要覆蓋 Frame Buffer 時,再從 Frame Data 取出節點資料做 Pixel Shader 的處理。


資料來源 :  OpenGL Insights [1]


  • PowerVR GPU 架構

看完上述對於 TBDR 架構的討論,接下來談談 Imagination Technologies 的 PowerVR 晶片。


PowerVR GPU 架構,資料來源 : Introduction to PowerVR for Developers [3]



TBDR 是 Imagination Technologies 的專利(註3),

PowerVR 就是根據 TBDR 架構製作的圖形裝置,

整個渲染流程可以分成兩個部分:

  1. Vertex Processing (Tiler)
  2. Per-Tile Rasterization (Renderer)

  • Vertex Processing (Tiler)

Tiler 流程,資料來源 : Introduction to PowerVR for Developers [3]


在每個 Frame,圖形裝置會將渲染物件的節點經過 Vertex Shader 的轉換,

將節點轉換到螢幕空間。

之後會通過 Tiler,將轉換後的節點分配到指定的 Tile,

並冊列清單儲存所有這個 Tile 內的節點資料,然後儲存在 Parameter Buffer 內。

這個 Parameter Buffer 是一個位於 System memory 內的儲存空間。

根據官方文件在 Parameter Buffer 內的資料都是經過特殊壓縮處理,

只占用極小的資料量,加快資料的傳輸。


  • Per-Tile Rasterization (Renderer)

Renderer 流程,資料來源 : Introduction to PowerVR for Developers [3]


裝置會重複 Vertex Processing 的動作直到需要更新 Frame Buffer 時,

才會執行 Renderer (ex. swap back and front buffer 或呼叫特殊指令 glflush、glfinish 等)。

當執行 Renderer 時,會以 Tilie 為單位執行 Renderer。

首先,會讀取該 Tile 在 Parameter Buffer 的節點清單資料。

然後透過 Image Synthesis Processor (之後簡稱 ISP) 將節點清單資料做 

Hidden Suface Removal(隱藏面遞除,簡稱 HSR)。

HSR 透過 Depth Buffer 和 Stencil Buffer 決定那些面不顯示,

找出畫面最前面的資料(i.e. 最靠近攝影機)。

接著做 Texture and Shading Processor(簡稱 TSP,i.e. Pixel Shader 或 Fragment Shader) 。

完成渲染之後,最後在寫入 Frame Buffer。


  • PowerVR 架構的疑問和推論

在看完官方提供了 PowerVR 的架構說明[3],

可以理解其效能擁有高評價的原因主要可以歸類成下列三點:

  1. 基於 TBR 架構,減少對 Frame Buffer 的存取次數,達到低耗電
  2. Deffered Shading,減少 Overdraw 帶來的效能衝擊
  3. 由硬體做物件排序 (i.e. HSR),可以更高速的決定那些面不顯示(註4)

從上述原因可以確定,PowerVR 對於不透明物件的渲染有極大的優勢。



但是一般遊戲很難完全不使用半透明 (ex. UI 、 特效 等...),

因此對於透明物件的渲染仍是有其必要性。

根據 PowerVR 對於效能優化的建議 [4],在非必要的情況下,

使用 Alpha Blend 取代 Alpha Test 對於效能有比較大的幫助。

但瀏覽網路卻會發現有些文章提出 Alpha Blend 對於效能的影響高於 Alpha Test。

這裡就衍生了兩個問題

  1. 為什麼官方會說 Alpha Blend 的效能比較好
  2. 為什麼在網路上會出現 Alpha Test 效能高於 Alpha Blend 的訊息

因此,本章節將對於兩個相反的事實去探討原因。

  • Alpha Blend

首先必須了解 PowerVR 對透明物件的處理流程,

根據 [5] 的描述,可以得知會對物件做 HSR,

當 HSR 沒有通過時(i.e. 被其他物件遮蔽), 

ISP 會繼續從 Parameter Buffer 找出下一個節點資料做 HSR,

這個時候流程和渲染不透明物件一樣。

但當透明物件通過了 HSR (i.e. 沒有被其他物件遮蔽),

ISP 會中斷運作,並渲染在這個時間點最上層的模型(i.e. 呼叫 Pixel Shader),

將結果儲存在 On-Chip 的 Colour Buffer,

之後在執行透明物件的渲染,從 Colour Buffer 取出背景顏色做 Alpha Blend。

Alpha Blend 的結果在回存到 Colour Buffer 做更新。

當完成更新後,ISP 將重新啟動,繼續從 Parameter Buffer 找出下一個節點資料做 HSR。

中斷 ISP 的目的是要確保渲染順序,讓半透明的渲染能夠正確。

根據上述的描述可以得知,由於背景資料是儲存在 On-Chip 的 Colour buffer 內,

所以相對於直接存取 Frame Buffer 的 Immediate-Mode Rendering,

Alpha Blend 的效率會比較高。

但仍然有 Overdraw 的問題 (講白話就是好一點,但用太多還是有效能問題)。

而且要中斷 ISP,停下來等待半透明渲染也會造成一些額外的效能消耗。


  • Alpha Test

Alpha Test 和 Alpha Blend 也是一樣,首先經過 HSR 處理。

如果被遮蔽,就同不透明物件一樣,

如果沒有被遮蔽,就會執行 TSP (i.e. Pixel shader),找出像素的透明值,

作為是否更新 Z Buffer 的判定。

由上述的說明可以得知,Alpha Test 只是在判斷是否更新 Z Buffer。

注意,這裡並不更新 Colour Buffer 的內容(註5),

這表示還是有 Overdraw 的問題,可以從下述的兩個狀況來分析

  1. 如果最後物件沒有被遮蔽,在寫入 Tile Buffer 時還是要再一次計算渲染結果
  2. 如果最後物件被遮蔽,在計算是否更新 Z軸時已經呼叫一次 TSP 了

無論是哪種狀況,該位置的 Pixel 都要做最少兩次以上的 TSP。

比較和 Alpha Blend 的差別,可以發現 Alpha Test 的 TSP 結果可能是個虛耗(i.e.沒有意義的執行)

Alpha Blend 的 TSP 執行一定會反映到最後畫面結果。

但 Alpha Test 可能會被之後的物件遮蔽,導致白作了一次的 TSP 計算。

因此,可以理解官方建議使用 Alpha Blend 取代 Alpha Test 的原因。


但 Alpha Test 就這麼百害而無一益嗎? 其實也不盡然。

在上面提到 Alpha Test 有虛耗的問題是因為之後可能會被其他物件所遮蔽。

但如果調整渲染順序讓 ISP 按照物件距離攝影機(畫面)由近到遠去執行 HSR,

使 Alpha Test 直接被 HSR 剔除,或確保通過 HSR 之後就不會被其他物件遮蔽。

將 Overdraw 的影響壓到最小,是否對效能有幫助?

tri-Ace Inc. 在 CEDEC 2013 [6] 的演講,就提出了這樣的報告。

tri-Ace Inc. 針對當時 6種常見的 mobile GPU ,

測試渲染不透明物件和 Alpha Test 物件的並存交叉渲染,測試結果如下


首先,讓不透明物件和 Alpha Test 物件交互從攝影機前向後方重疊排列。

接著根據三種渲染順序規則作測試,紀錄其 FPS 結果,將結果列於下方圖表。

其中,淺藍色是由後往前,紅色是由前往後(不透明開始),

深藍是由前往後(Alpha Test 物件開始)。

雖然結果都很類似,但我將焦點放在 PowerVR,

可以觀察到由後往前的效能最差(淺藍),可以推斷對 Alpha Test 物件虛耗了不少 TSP 計算。

由前往後(不透明開始)的效能最好(紅色),因為後面的所有物件都在 HSR 被剔除。

由前往後(Alpha Test)的效能(深藍)比由前往後(不透明開始)的效能(紅色)稍微低一點,

因為對最前面的 Alpha Test 物件作兩次 TSP(一次更新Z Buffer、一次更新畫面結果)。

從結果可以得知如果能聰明的排序渲染順序,

Alpha Test 帶來的效能衝擊並不會有想像中的嚴重。

這也可以解釋為什麼網路上有些文章會提出 Alpha Test 效能優於 Alpha Blend.

這些文章的測試方法都是用到大量的 Alpha Test (Alpha Blend) 物件去做渲染,然後比較 FPS。

因為 Alpha Test 會遮蔽後面的物件,所以不是所有的物件都會執行 TSP。

而 Alpha Blend 則是所有物件的 TSP都被執行,當然效能會低於 Alpha Test 結果。


  • 結論

綜合上述分析,從硬體架構優化渲染效能可以歸納出下列幾個準則

  1. 盡可能不要使用半透明或 Alpha Test 物件,減少 Overdraw
  2. 不透明、半透明和 Alpha Test 物件的渲染順序不要交叉渲染 (ex. 不透明 -> 半透明 -> 不透明),讓相同種類的物件集中渲染,避免中斷ISP 的運作,增加等待 TSP 和 Blend 的時間;當有必要同時對三種物件渲染時,官方推薦 [4] 的順序是 不透明 -> Alpha Test -> 半透明,這種順序可以讓 HSR 的效用發揮到最大。
  3. 當開始渲染 Frame Buffer 時,若不需要使用 Frame Buffer 的資料 (i.e.上一個 Frame 的畫面結果),記得呼叫 glClear 指令;由於 TBR 架構會複製 Frame Buffer 到 On-Chip Memory, glClear 指令可以減少這個複製動作,增加運作效能。

本篇的討論就到此結束,下一篇會從軟體(i.e. 程式編寫)的角度去分析如何優化系統效能。








  • 附註
1.TBR 的目的在於減少因為對 Frame Buffer 的存取而消耗大量的電力,
   因此目前主流的 mobile GPU 晶片都是採用 TBR 架構。
   但桌上型 PC 沒有耗電問題,所以是直接對 Frame Buffer 操作,
   可以省去 TBR 的 Tile 管理(包括分配、讀、寫和壓縮) 的負擔。
   這種直接對 Frame Buffer 存取的做法稱作 Immediate-Mode Rendering。

2.泛指對模型節點的處理,包含座標轉換、 Clip 、 Tile 分配等,

3.Imagination Technologies 認為 TBR 的概念裡並沒有提到延遲寫入 Frame Buffer,
   因此認為 PowerVR 的 HSR 才是真正實作出 TBDR 的晶片。
   但對 ARM 而言, TBR 的 Tiler 本身已經是一個延遲寫入 Frame Buffer 的概念,
   因此沒有特地提出 TBDR 這個架構。
   事實上,ARM 的 Mali 使用了 Forward Pixel Killing 的技術,
   達成和 PowerVR 的 HSR 一樣來減少 Overdraw 的發生。
   所以 TBR 和 TBDR 的差異就看各廠商怎麼解讀。

4.HSR 的計算是使用 On-Chip 的儲存空間,因此可以快速更新計算結果。

5.Alpha Test 是否更新 Colour Buffer 我並沒有找到相關的文獻來證明我的推論,
   我之所以判斷沒有更新 Colour Buffer 主要根據 下列兩個論點:
   a. 根據 [3] 提示的 Renderer 流程圖,Alpha Test 完成後箭頭指向 HSR 而沒有指向 Colour Buffer
   b. 根據 [4] 如果有更新 Colour Buffer,官方應該不會建議使用 Alpha Blend 取代 Alpha Test,
       因為 Alpha Test 會更新 Z Buffer,可增加遮蔽面積。
  
   



沒有留言:

張貼留言