.NET JIT是否会内联一个调用另一个小函数的小函数?

时间:2010-07-31 08:56:07

标签: .net jit inlining

我想知道 - .NET JITter是否会递归内联从其他小函数调用的小函数?

仅举例:

public static float Square(float value)
{
    return value * value;
}

public static float Cube(float value)
{
    return Square(value) * value;
}

如果我从某个地方拨打Cube,它会一直内联,还是最终会调用Square的函数?

而且,如果是这样的话,它会有多深才能进行内联? (说我疯狂到以同样的方式实现QuarticQuintic功能。)

1 个答案:

答案 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。