移動端 Shader 性能優化常用點


前提:

1. GPU的架構為SIMD(單指令多數據流架構),即在GPU上面執行N個數據和1個數據的效率是一樣的,指令相同的情況下。所以並行的計算盡量都放到GPU上。

2. GPU的設計基礎為向量計算。(即向量乘法和單個float 的乘法效率一樣。【CPU需要執行多次】)

 

性能可優化點:

1. 合並單個計算為向量運算。

float x;
float y;

x = x *a; y = y * b;

 將上面的寫法修改為下面的效率會更高。

float2 v = float2(x,y);
v = v * float2(a,b);

  修改后的寫法只需要執行一次。

2. 不要使用條件判斷, FOR 語句。(性能不高,會涉及到同步)。

float4 a ;
if( b > 1){
  a.a = 1;
} else {
 a.a = 0.5;
}

  上面的條件判斷可以使用 內置函數 step 進行替換。

flaot4 a;

float t = step(b, 1.0);
a = tmp * 0.5 + (1.0 - tmp);

  替換的根本原因在於動態分支

3. 盡可能使用內置函數。(內置函數大部分都使用了GPU的特殊特性)。

  高級函數,如非必要,盡量不要使用,如 sin,cos, sinh, cosh等。( Asin, Acos, Atan非常高。)

4. swizzle 的效率高於單步賦值。

float4 a = float4(1.0, 1.0, 1.0, 1.0);

a.w = 2.0;
a.z = 2.0;

  上面的代碼修改為下面的效率更高。

float4 a = float4(1.0, 1.0, 1.0, 1.0);
a.wz= float2(2.0, 2.0);

  

5. 如果非必要,盡量不使用高精度。(高精度32位,中等精度為16位,低精度為12位。)

  附:降低精度在某些情況下不能起到提升性能的作用。

6. 只計算需要的東西。運算盡量放在VS或者腳本中進行。

  原因:只計算需要的東西, 可以減少傳輸的數據量,避免過多的頂點計算,如:過多的光照,或者光照太復雜。

  通常情況下,需要渲染的像素比頂點數多,而頂點數又比物體數多很多。所以如果可以,盡量將運算從 FS 移到 VS,或直接通過 script 來設置某些固定值;

  並不是所有的計算都適合放到腳本中進行,(CPU的計算結果傳遞給GPU里面也有性能消耗)

7. 其他

  alpha test, clip , Color Mask 慎用。不同平台上消耗不一樣,部分機型可能性能會非常差。

 

 

=========================以下內容為轉載=============================

定位渲染通道瓶頸的方法
轉自:http://blog.csdn.net/rabbit729/article/details/6398343

一般來說, 定位渲染通道瓶頸的方法就是改變渲染通道每個步驟的工作量, 如果吞吐量也改變了, 那個步驟就是瓶頸.。找到了瓶頸就要想辦法消除瓶頸, 可以減少該步驟的工作量, 增加其他步驟的工作量。
  一般在光柵化之前的瓶頸稱作”transform bound”, 三角形設置處理后的瓶頸稱作”fill bound”

定位瓶頸的辦法:
1. 改變幀緩沖或者渲染目標(Render Target)的顏色深度(16 到 32 位), 如果幀速改變了, 那么瓶頸應該在幀緩沖(RenderTarget)的填充率上。
2. 否則試試改變貼圖大小和貼圖過濾設置, 如果幀速變了,那么瓶頸應該是在貼圖這里。
3. 否則改變分辨率.如果幀速改變了, 那么改變一下pixel shader的指令數量, 如果幀速變了, 那么瓶頸應該就是pixel shader. 否則瓶頸就在光柵化過程中。
4. 否則, 改變頂點格式的大小, 如果幀速改變了, 那么瓶頸應該在顯卡帶寬上。
5. 如果以上都不是, 那么瓶頸就在CPU這一邊。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM