当我编译HLSL着色器pow(foo, 6)或者pow(foo, 8),编译器创建具有比如果我创建相同的着色器约10多指令集会pow(foo, 9)或pow(foo,10)或pow(foo,7).
这是为什么?
说明或指令槽?
该pow指令需要三个3个插槽,而mul指令只需要1个.
(参考:指令集:vs_2_0,ps_2_0,vs_3_0,ps_3_0)
在编写着色器时,通常希望保持指令槽倒计时,因为着色器模型定义的指令槽数量有限.它也是一种估算着色器计算复杂度的合理方法(即:运行速度有多快).
1的幂显然是无操作.2的幂需要一条mul指令.3和4的幂可以用两个mul指令完成.5,6和8的功率可以用三个mul指令完成.
(我想这个优化背后的数学是由Jim Lewis发布的链接解释的.)
编译器mul在单pow条指令上选择三条指令(两者都使用相同数量的指令槽)的可能原因是pow具有常量指数的指令还需要分配一个常量寄存器来存储该指数.显然,使用三个指令槽并且没有常量寄存器比使用三个槽和一个常量寄存器更好.
(为什么你会得到10个以上的指令?我不确定,它将取决于你的着色器代码.HLSL编译器以优化的名义做了很多奇怪而美妙的事情.)
如果你使用fxc带有选项的DirectX SDK中的着色器编译器()/Cc /Fc output.html,它将为你提供一个可以检查的好的汇编读数,包括所用指令槽数的计数.