6

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

举个例子:

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

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

如果我Cube从某个地方调用,它会一直内联,还是会以函数调用结束Square

并且,如果是这样,内联将递归多深?(假设我很疯狂地以同样的方式实现 a QuarticorQuintic函数。)

4

1 回答 1

10

不幸的是,你选择了一个不好的例子。x86 JIT 编译器不会内联返回浮点数的方法。不是 100% 确定为什么,我认为它确实可以避免在 FPU 中将浮点数转换为 80 位浮点值时出现问题。内部精度为 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) 直接传递结果。很不错吧?

使用双精度,而不是浮点数。

于 2010-07-31T15:12:24.740 回答