粗略判斷Shader每條代碼的成本

此文轉自: https://zhuanlan.zhihu.com/p/34629262node

 

Unity對Shader文件進行編譯的時候,DX9和DX11的版本會直接生成彙編碼。函數

length(i.worldPos)

DX9測試

dp4 r0.x, v0, v0
rsq r0.x, r0.x
rcp_pp oC0, r0.x

DX11編碼

dp4 r0.x, v1.xyzw, v1.xyzw
sqrt o0.xyzw, r0.xxxx

 

因爲這些代碼是最終的指令,大部分指令執行時間是「差很少」的,能夠用來預估計算量。但移動平臺則是各廠商驅動各自進行的編譯,各家都不同,很差判斷。spa

但DX9畢竟針對的是很是古老的硬件,很難想象現代GPU還會和它保持同樣。實際的指令應該會更接近於DX11。3d

如下爲列表(用|隔開的數據,前面的部分是計算單份量時的指令數,後面的部分是計算float4時的指令數)code

總結一下即是:orm

  • 反三角函數很是費
  • abs和saturate是免費的
  • 除了反三角函數外,fmod和smoothstep比預期更費
  • log,exp,sqrt(單份量)的成本實際上很低,因此由他們組合成的pow也不高
  • sin,cos在DX11使用了專門一條單指令,成爲了低成本函數

另外還有個基本常識:絕大部分GPU是一次性計算4個份量,計算一個float4和只計算單個float耗時是同樣的。當計算float時,剩下三個份量的時長會被浪費。blog

 

然而,每條指令的時間成本確實多是不同的。這個和具體硬件有關。get

很難找到移動平臺具體GPU的數據,能夠參考下文看看一些主流GPU的狀況,相信他們老是有一些共性的。

shader function or instruction cost (performance)

 

結果是,1/x, sin(x), cos(x), log2(x), exp2(x), 1/sqrt(x)這些指令的時間成本是同樣的,並且和普通的四則運算很接近(我的猜想是經過查表實現的)。

可是sin,cos畢竟在舊硬件上成本較高,因爲不清楚硬件的具體狀況,仍是要儘量少用。

 


 

預估成本還有一個辦法,是根據公開的GPU的GFLOPS(Floating-point Operations Per Second每秒執行浮點運算次數)

GPU GFLOPS​gflops.surge.sh圖標

來評估每一個着色器理論極限算力,便能知道一個着色器裏能夠容許多少條基本指令。

這固然很不精確,由於紋理採樣,頂點,光柵化等等衆多成本都沒有考慮在內,可是有必定的參考價值。

iPhone 4s使用的芯片是Apple A5,它的FLOPS是12.8G,屏幕分辨率是960x640,分到一幀的一個像素後,結果是

12.8*1024^3/960/640/60 = 372。

根據FLOPS的定義,時間最短的基本指令「乘加(MAD)」須要花掉2FLOPS,那麼單個屏幕像素能執行186條指令。

假設Overdraw是5,那麼一個像素着色器能執行37指令。

 

雖然37指令這個結果顯然比實際多多了,但起碼是在合適的數量級範圍內。能夠經過幀率測試來計算「損耗比例」究竟是多少。

並且,這樣作咱們其實獲得了一個上限值。若是你在像素單元的指令數超過了37(好比用了兩次atan2),那從物理角度是絕對不可能達到滿幀的。

相關文章
相關標籤/搜索