此文转自: 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
另外还有个基本常识:绝大部分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每秒执行浮点运算次数)
来评估每一个着色器理论极限算力,便能知道一个着色器里能够容许多少条基本指令。
这固然很不精确,由于纹理采样,顶点,光栅化等等众多成本都没有考虑在内,可是有必定的参考价值。
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),那从物理角度是绝对不可能达到满帧的。