優化shader程式的一些tips

2021-07-27 03:32:18 字數 1727 閱讀 7298

在寫shader的時候,其實一些寫法對於其執行影響非常大,而且由於gpu和cpu在架構上的不同,**的優化思想也不一樣,最近一直在寫幾個shader,為了效能問題,查閱了很多資料,把一些tips總結下來。

首先要樹立幾個思想:

1.gpu是simd的架構,即單指令多資料流架構,即在gpu上同時執行n個資料和執行1個資料的效率是一樣的,我們要

盡量的把並行的計算搬到gpu上

2.gpu是以向量計算為基礎設計的,也就是說在gpu上執行乙個向量乘法和執行乙個float的乘法的效率是一樣的,

並不向cpu那樣要多執行幾次

所以1.盡量把一些計算合併成向量計算,記住乙個向量計算和乙個float計算那樣快!

比如 float x,y;

x = x * a;

y = y * b;

不如寫成 float2 v = float2(x,y);

v = v*float2(a,b);

因為前一種寫法是兩次乘法計算,而後一種只要1次

2.不要在gpu裡面用分支或者條件判斷這種語句,儘管大多數gpu 的shader支援這種語法,但是多數gpu裡面的

這種控制語句涉及到一些同步等消耗的操作,

其實大多數這種語句都可以用數值的方式替代。

比如 你想寫

float4 a;

if(b > 1)

else

可以改寫成

float4 a;

float tmp = step(b,1);

a = tmp * 0.5 + (1-tmp);

if else可以被step出來的0 或1的乘法代替又比如

float4 a;

if(b && c || d && e)

else

可以寫成

float4 a;

float tmp = step(1, (float)b*(float)c + float(d)*float(e));

a = tmp + (1-tmp) * 0.5;

&& 我們用轉換到float後的乘法代替,||可以被判斷加法step 1代替

而這種操作,尤其是shader內建的函式比條件判斷和分支的效率要高很多,別忘了,gpu純粹是為了計算的,而不是

做判斷3.盡量使用shader為我們提供的內建函式,這些內建的函式比我們想象的要快很多,往往應用了某些gpu的特殊

特性。比如要比較a和b誰大用max(a,b),還有例如上面反覆用的step,雖然你可以寫用(float)(a>=1)來替換step(1,a),

但是這還是沒有內建函式更快的,包括常用的saturate()把乙個數歸到0-1,總之一句話,如果能用乙個內建函式替換

你的某些**,就盡量替換。而且這些內建函式基本上都是支援對向量操作的,所以如果用step(a,fixed3(1,2,3))其

實只是一條指令,但是卻可以同時返回用a同1 2 3分別比較的結果。

4.使用swizzle是非常快的,例float4 a = float4(1,1,1,1),用a.wz = float2(2,3)要比 a.w=3; a.z=2要高效很多

5.使用合適的資料型別,大部分gpu支援f的數值型別基本上分為fixed half float,分別是12位的定點數,16位的浮

點數以及32位的浮點數,盡可能的選擇位數更少的資料型別來加快操作

摘錄一些有關Shader優化的問題

1。減少代數運算.如果可以自己展開的先展開利於編譯器優化 例如 普通的球面帖圖投射常常表示為 p sqrt rx2 ry2 rz 1 2 這可以展開為 p sqrt rx2 ry2 rz2 2rz 1 2.不要把向量值放入含有多個內插值的標量部件中 tangent float4 tangentvec...

rake db migrate學會的一些tips

在對著書本學習ror的時候,執行rake db migrate出現了一堆問題 1.首先rake版本衝突,本地是10,然後需要是0.8.7,解決辦法 先解除安裝最新版本rake gem unistall rake v 10.0.3,然後安裝rake0.8.7 gem install rake 0.8....

rake db migrate學會的一些tips

在對著書本學習ror的時候,執行rake db migrate出現了一堆問題 1.首先rake版本衝突,本地是10,然後需要是0.8.7,解決辦法 先解除安裝最新版本rake gem unistall rake v 10.0.3,然後安裝rake0.8.7 gem install rake 0.8....