6

知りたいのですが、.NET JITter は、他の小さな関数から呼び出された小さな関数を再帰的にインライン化しますか?

ちょうど例:

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

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

どこかから呼び出すCubeと、インライン化されますか、それとも への関数呼び出しになりSquareますか?

もしそうなら、インライン化を行うためにどれくらい深く再帰しますか? (私が同じ方法でQuarticorQuintic関数を実装するのに十分夢中だったとしましょう。)

4

1 に答える 1

10

残念ながら、あなたは悪い例を選びました。x86 JITコンパイラは、floatを返すメソッドをインライン化しません。理由は100%わかりませんが、FPUでfloatが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 に答える