前提:
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這一邊。