我想知道 - .NET JITter是否会递归内联从其他小函数调用的小函数?
仅举例:
public static float Square(float value)
{
return value * value;
}
public static float Cube(float value)
{
return Square(value) * value;
}
如果我从某个地方拨打Cube
,它会一直内联,还是最终会调用Square
的函数?
而且,如果是这样的话,它会有多深才能进行内联? (说我疯狂到以同样的方式实现Quartic
或Quintic
功能。)
答案 0 :(得分:10)
不幸的是你选了一个坏榜样。 x86 JIT编译器不会内联返回float的方法。不是100%肯定为什么,我认为当浮点数转换为FPU中的80位浮点值时,它确实可以避免一致的问题。内部精度为80位,但当80位值在刷回内存时被截断回32位值时,这些额外位会被切掉。保持FPU中的值太长可防止发生此截断并更改计算结果。
如果用double替换float并编译此代码:
static void Main(string[] args) {
Console.WriteLine(Cube(2.0));
}
然后在启用JIT优化器时生成此机器代码:
00000000 push ebp ; setup stack frame
00000001 mov ebp,esp
00000003 call 6DA2BEF0 ; Console.get_Out()
00000008 fld qword ptr ds:[010914B0h] ; ST0 = 8.0
0000000e sub esp,8 ; setup argument for WriteLine
00000011 fstp qword ptr [esp]
00000014 mov ecx,eax ; call Console.Out.WriteLine
00000016 mov eax,dword ptr [ecx]
00000018 call dword ptr [eax+000000D0h]
0000001e pop ebp ; done
0000001f ret
它不仅内联函数,还能够在编译时评估表达式。并通过调用Console.WriteLine(8.0)直接传递结果。很好啊?
使用double,而不是float。