Can I check if the C# compiler inlined a method ca

2019-01-18 02:21发布

I'm writing an XNA game where I do per-pixel collision checks. The loop which checks this does so by shifting an int and bitwise ORing and is generally difficult to read and understand.

I would like to add private methods such as private bool IsTransparent(int pixelColorValue) to make the loop more readable, but I don't want the overhead of method calls since this is very performance sensitive code.

Is there a way to force the compiler to inline this call or will I do I just hope that the compiler will do this optimization?

If there isn't a way to force this, is there a way to check if the method was inlined, short of reading the disassembly? Will the method show up in reflection if it was inlined and no other callers exist?

Edit: I can't force it, so can I detect it?

9条回答
做自己的国王
2楼-- · 2019-01-18 02:35

No you can't. Even more, the one who decides on inlining isn't VS compiler that takes you code and converts it into IL, but JIT compiler that takes IL and converts it to machine code. This is because only the JIT compiler knows enough about the processor architecture to decide if putting a method inline is appropriate as it’s a tradeoff between instruction pipelining and cache size.

So even looking in .NET Reflector will not help you.

查看更多
Explosion°爆炸
3楼-- · 2019-01-18 02:39

The only way to check this is to get or write a profiler, and hook into the JIT events, you must also make sure Inlining is not turned off as it is by default when profiling.

查看更多
The star\"
4楼-- · 2019-01-18 02:45

"You can check System.Reflection.MethodBase.GetCurrentMethod().Name. If the method is inlined, it will return the name of the caller instead."

--Joel Coehoorn

查看更多
Evening l夕情丶
5楼-- · 2019-01-18 02:47

You can detect it at runtime with the aforementioned GetCurrentMethod call. But, that'd seem to be a bit of a waste[1]. The easiest thing to do would to just ILDASM the MSIL and check there.

Note that this is specifically for the compiler inlining the call, and is covered in the various Reflection docs on MSDN.

If the method that calls the GetCallingAssembly method is expanded inline by the compiler (that is, if the compiler inserts the function body into the emitted Microsoft intermediate language (MSIL), rather than emitting a function call), then the assembly returned by the GetCallingAssembly method is the assembly containing the inline code. This might be different from the assembly that contains the original method. To ensure that a method that calls the GetCallingAssembly method is not inlined by the compiler, you can apply the MethodImplAttribute attribute with MethodImplOptions.NoInlining.

However, the JITter is also free to inline calls - but I think a disassembler would be the only way to verify what is and isn't done at that level.

Edit: Just to clear up some confusion in this thread, csc.exe will inline MSIL calls - though the JITter will (probably) be more aggressive in it.

[1] And, by waste - I mean that (a) that it defeats the purpose of the inlining (better performance) because of the Reflection lookup. And (b), it'd probably change the inlining behavior so that it's no longer inlined anyway. And, before you think you can just turn it on Debug builds with an Assert or something - realize that it will not be inlined during Debug, but may be in Release.

查看更多
兄弟一词,经得起流年.
6楼-- · 2019-01-18 02:50

Be aware that the XBox works different.

A google turned up this:

"The inline method which mitigates the overhead of a call of a method. JIT forms into an inline what fulfills the following conditions.

  • The IL code size is 16 bytes or less.
  • The branch command is not used (if sentence etc.).
  • The local variable is not used.
  • Exception handling has not been carried out (try, catch, etc.).
  • float is not used as the argument or return value of a method (probably by the Xbox 360, not applied).
  • When two or more arguments are in a method, it uses for the turn declared.

However, a virtual function is not formed into an inline."

http://xnafever.blogspot.com/2008/07/inline-method-by-xna-on-xbox360.html

I have no idea if he is correct. Anyone?

查看更多
Animai°情兽
7楼-- · 2019-01-18 02:52

There is a new way to encourage more agressive inlining in .net 4.5 that is described here: http://blogs.microsoft.co.il/blogs/sasha/archive/2012/01/20/aggressive-inlining-in-the-clr-4-5-jit.aspx

Basically it is just a flag to tell the compiler to inline if possible. Unfortunatly, it's not available in the current version of XNA (Game Studio 4.0) but should be available when XNA catches up to VS 2012 this year some time. It is already available if you are somehow running on Mono.

[MethodImpl(MethodImplOptions.AggressiveInlining)] 
public static int LargeMethod(int i, int j)
{ 
    if (i + 14 > j) 
    { 
        return i + j; 
    } 
    else if (j * 12 < i) 
    { 
        return 42 + i - j * 7; 
    } 
    else 
    { 
        return i % 14 - j; 
    } 
}
查看更多
登录 后发表回答