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

And*_*ell 6 .net jit inlining

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

仅举例如:

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

public static float Cube(float value)
{
    return Square(value) * value;
}
Run Code Online (Sandbox Code Playgroud)

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

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

Han*_*ant 10

不幸的是你选了一个坏榜样.x86 JIT编译器不会内联返回float的方法.不是100%肯定为什么,我认为当浮点数转换为FPU中的80位浮点值时,它确实可以避免一致的问题.内部精度为80位,但当80位值在刷回内存时被截断回32位值时,这些额外位会被切掉.保持FPU中的值太长可防止发生此截断并更改计算结果.

如果你用double替换float并编译这段代码:

static void Main(string[] args) {
    Console.WriteLine(Cube(2.0));
}
Run Code Online (Sandbox Code Playgroud)

然后在启用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
Run Code Online (Sandbox Code Playgroud)

它不仅内联函数,还能够在编译时评估表达式.并通过调用Console.WriteLine(8.0)直接传递结果.挺好的吧?

使用double,而不是float.