代码之家  ›  专栏  ›  技术社区  ›  Andrew Russell

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

  •  6
  • Andrew Russell  · 技术社区  · 15 年前

    我想知道-将.NET抖动递归内联小函数调用从其他小函数?

    举个例子:

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

    Cube Square ?

    如果是这样的话,那么内联会有多深(说我疯了,竟然实施了一个 Quartic Quintic

    1 回复  |  直到 15 年前
        1
  •  10
  •   Hans Passant    15 年前

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

    如果将float替换为double并编译以下代码:

    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)直接传递结果。不错吧?

    使用双精度,而不是浮动。