1

我正在将 x86 应用程序移动到 x64 并发现编译器没有内联函数。甚至很小(<32 字节 IL 甚至是空的)。即使使用编译器选项MethodImplOptions.AggressiveInlining

而在 x86 中,所有小函数(以及带有编译器选项的简单大函数)都被内联而没有问题。

x64 中有什么方法可以告诉编译器内联它们吗?

例如,以下带有“目标平台”= 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 jitter 编译为 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 回答
1

在我的电脑中(.Net 4.5 x64)

如果我使用AggressiveInlining,x86(目标所有 cpu 首选 32 位)需要 36 毫秒,x64(目标所有 cpu 取消选中首选 32 位)需要 8 毫秒。

如果我使用NoInlining,x86 需要 240 毫秒,x64 需要 270 毫秒。

所以,它肯定是内联的

于 2013-05-07T10:17:43.237 回答