为什么会在.NET JIT编译器决定不inline或优化掉的呼叫清空有没有副作用静态方法? [英] Why would the .NET JIT compiler decide to not inline or optimize away calls to empty static methods that have no side effects?

查看:252
本文介绍了为什么会在.NET JIT编译器决定不inline或优化掉的呼叫清空有没有副作用静态方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我观察.NET JIT编译器不内联或优化掉的呼叫清空有没有副作用,这是一个有点令人惊讶的给出了一些bespoken在线资源的静态方法。

I think I'm observing the .NET JIT compiler not inlining or optimizing away calls to empty static methods that have no side effects, which is a bit surprising given some bespoken online resources.

我的环境是在x64上的Visual Studio 2013中,Windows 8.1,.NET框架4.5。

My environment is Visual Studio 2013 on x64, Windows 8.1, .NET Framework 4.5.

鉴于这种简单的测试程序(的 https://ideone.com/2BRCpC

Given this simple test program (https://ideone.com/2BRCpC)

class Program
{
    static void EmptyBody()
    {
    }

    static void Main()
    {
        EmptyBody();
    }
}



发布版本与上述程序的优化产生以下MSIL为 EmptyBody

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       6 (0x6)
  .maxstack  8
  IL_0000:  call       void Program::EmptyBody()
  IL_0005:  ret
} // end of method Program::Main

.method private hidebysig static void  EmptyBody() cil managed
{
  // Code size       1 (0x1)
  .maxstack  8
  IL_0000:  ret
} // end of method Program::EmptyBody

这并不奇怪,MSIL包含通话到 EmptyBody ,因为C#编译器预计不会inline或优化掉这样的电话。但是,我认为,JIT编译器会随即开始或优化掉这一呼吁。但是,这似乎并没有发生。

It's not surprising that the MSIL contains a call from Main to EmptyBody, since the C# compiler isn't expected to inline or optimize away calls like that. However, I thought that the JIT compiler would then inline or optimize away that call. But that doesn't seem to happen.

如果我运行上面的程序,并在主要进入调试器 ,生成的程序集是这样的:

If I run the above program and break into the debugger in Main, the generated assembly is this:

00572621  mov         ebp,esp  
00572623  cmp         dword ptr ds:[4320B84h],0  
0057262A  je          00572631  
0057262C  call        73E6AF20  
00572631  call        dword ptr ds:[4321578h]  

指令指针立即设置为最后一行在00572631,这是调用 EmptyBody 。走进 EmptyBody ,生成的程序集被发现是

The instruction pointer is immediately set to the last line at 00572631, which is the call to EmptyBody. Stepping into EmptyBody, the generated assembly is found to be

00BD2651  mov         ebp,esp  
00BD2653  cmp         dword ptr ds:[4B00B84h],0  
00BD265A  je          00BD2661  
00BD265C  call        73E6AF20  
00BD2661  nop  
00BD2662  pop         ebp  
00BD2663  ret

指令指针立即设置为 NOP 线在00BD2661,它没有做任何事情,我无法猜测为什么它摆在首位的产生。

The instruction pointer is immediately set to the nop line at 00BD2661, which doesn't do anything, and I cannot guess why it's generated in the first place.

由于这两个组件片段以上的份额相同4指令的头,我以为这只是常规的方法进入锅炉板,其中堆栈,这样的设置。我渴望学习了解这些反复出现的指令会做,虽然:

Given that the two assembly snippets above share the same 4-instruction header, I assume that's just the regular method entry boiler plate where the stack and such is set up. I'm keen to learn to know what these recurring instructions would do, though:

00BD2653  cmp         dword ptr ds:[4B00B84h],0  
00BD265A  je          00BD2661  
00BD265C  call        73E6AF20  

总之,主要问题是:为什么调用空浓郁的静态方法 EmptyBody

Anyhow, the main question is: Why does the JIT compiler produce assembly that calls the empty-bodied static method EmptyBody?

推荐答案

挖掘远一点之后,原来我可以回答这个问题我自己。截至 http://blogs.msdn.com/b/vancem/archive解释/2006/02/20/535807.aspx ,调试器下观察优化的发布版本的拆卸将默认影响JIT编译器。

After digging a bit further, it turns out I can answer this question myself. As explained at http://blogs.msdn.com/b/vancem/archive/2006/02/20/535807.aspx , observing the disassembly of an optimized release build under the debugger will by default affect the JIT compiler.

取消勾选这些


  • '禁止模块负载JIT优化

  • 启用仅我的代码

在VS>工具>调试>常规,将显示真正的JIT编译的结果,这为呼叫 EmptyBody 在我的上面是这样的:

under VS > Tools > Debugging > General, will show the "real" JIT compilation result, which for the call to EmptyBody in my Main above is this:

004C2620  ret

意思就是说调用 EmptyBody 完全去除,这是预期,世界仍然生活在一个幸福的,有点可预见的地方:)

Meaning that the call to EmptyBody is completely removed, which is what was expected and the world is still a happy and somewhat predictable place to live in :)

这篇关于为什么会在.NET JIT编译器决定不inline或优化掉的呼叫清空有没有副作用静态方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆