1

x86アプリケーションをx64に移動していますが、コンパイラーによって関数がインライン化されていないことがわかりました。小さい場合でも(<32バイトIL、さらには空)。コンパイラオプションを使用してもMethodImplOptions.AggressiveInlining

x86では、すべての小さな関数(およびコンパイラオプションを使用した単純な大きな関数)が問題なくインライン化されます。

x64で、コンパイラにインライン化するように指示する方法はありますか?

たとえば、「TargetPlatform」= x86を使用した次のコードはループするだけで、x64を使用した場合もEmptyFunction()を1億回呼び出します。

void LoopFunction()
{
    Stopwatch watch = new Stopwatch();
    watch.Start();
    for (int i = 0; i < 100000000; i++)
    { EmptyFunction(); }
    watch.Stop();
    MessageBox.Show(watch.Elapsed.ToString());
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void EmptyFunction() { }
4

2 に答える 2

2

.NET 3.5 ジッタによって 64 ビット モードにコンパイルされた for() ループ

0000002e  xor         r11d,r11d 
00000031  add         r11d,4 
            for (int i = 0; i < 100000000; i++) { EmptyFunction(); }
00000035  cmp         r11d,5F5E100h 
0000003c  jl          0000000000000031 

.NET 4.5 ジッターによって:

0000003a  xor         eax,eax 
0000003c  nop         dword ptr [rax] 
00000040  add         eax,4 
            for (int i = 0; i < 100000000; i++) { EmptyFunction(); }
00000043  cmp         eax,5F5E100h 
00000048  jl          0000000000000040 

呼び出しはありません。本来あるべきように、ループだけが生き残りました。奇妙な NOP 命令は、分岐先を揃えるためにあります。

オプティマイザーが無効になるため、必ずリリース ビルドを使用し、デバッガーの使用には注意してください。ツール+オプション、デバッグ、一般で修正し、「モジュールのロード時にJIT最適化を抑制する」オプションのチェックを外します。

于 2013-02-13T18:40:31.307 に答える