我正在将x86应用程序移动到x64,并发现编译器没有内联任何函数。甚至很小(<32字节IL甚至是空的)。即使使用编译器选项MethodImplOptions.AggressiveInlining
。
在x86中,所有小函数(以及带编译器选项的简单大函数)都没有问题。
在x64中是否有任何方法告诉编译器内联它们?
例如,下面的代码“Target Platform”= 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() { }
答案 0 :(得分:2)
由.NET 3.5抖动编译为64位模式的()循环
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指令用于对齐分支目标。
请务必使用Release版本并小心使用调试器,因为它会禁用优化程序。使用工具+选项,调试,常规修复此问题,取消选中“在模块加载时抑制JIT优化”选项。
答案 1 :(得分:1)
在我的电脑(.Net 4.5 x64)
中如果我使用AggressiveInlining
,x86(目标所有cpu 32位首选)需要36 ms,x64(目标所有cpu取消选中32位首选)需要8 ms。
如果我使用NoInlining
,则x86需要240 ms,x64需要270 ms。
所以,它肯定是内联的