none
Method inlining? RRS feed

  • Question

  • I've been looking around for a way to force certain methods to be inlined.  Unfortunately, .Net doesn't seem to provide this functionality.  The documentation says that .Net will attempt to inline functions where possible, but it doesn't ever give anymore information than this.  So heres my question:

    1) Is it possible to tell if a method will be inlined or not?  2) do any of you know of any hacks that will force a method to be inlined?


    Thanks for your time
    Monday, June 30, 2008 2:13 AM

Answers

  • Well, here are two related blog posts that describe in more detail what the JITter inlines:
    http://blogs.msdn.com/ericgu/archive/2004/01/29/64717.aspx
    http://blogs.msdn.com/ricom/archive/2004/01/14/58703.aspx

    The primary purpose of inlining is for trivial property getters & setters.  When it gets much more complex than that you probably don't get inlining.  Also, declaring a method as virtual definitely prevents it from being inlined.

    As for figuring out exactly what gets inlined, that's quite difficult because inlining is handled by the JIT compiler at runtime so even ILDASM won't help you.  I'm not aware that inlining decisions are exposed or recorded in any way, either.  You could use Visual Studio to break into the application after the methods in question have been JIT-compiled and then look at the assembly, but you'd need to turn off debug mode for realistic results.

    Perhaps it's faster to just try separate and embedded methods and benchmark each case...
    • Edited by Christoph Nahr Monday, June 30, 2008 7:34 AM Spelling
    • Marked as answer by pdev.mich Monday, June 30, 2008 8:55 AM
    • Marked as answer by pdev.mich Monday, June 30, 2008 8:55 AM
    • Marked as answer by pdev.mich Monday, June 30, 2008 8:55 AM
    Monday, June 30, 2008 7:33 AM

All replies

  • That isn't supported in .Net.  See Eric Gunnerson's log entry @  http://blogs.msdn.com/ericgu/archive/2004/01/29/64644.aspx for more details.

    It even mentions a hack if your read the comments.  Of course, the hack is to write the code in VC++ and you still are not guaranteed the inlining that you are looking for.

    Michael Fischer
    Monday, June 30, 2008 2:36 AM
  • Thanks for the response Michael, but it didn't really help.  I was already aware .Net doesn't officially support forcing method inlining.  What I'm looking for here is to tell if .Net decides to inline my functions or not.

    I'm writing a video encoder/decoder.  For clarity, it needs to be broken up into methods... but the overhead of all of the calls would be immense.  So my question still stands.

    Monday, June 30, 2008 2:50 AM
  • Well, here are two related blog posts that describe in more detail what the JITter inlines:
    http://blogs.msdn.com/ericgu/archive/2004/01/29/64717.aspx
    http://blogs.msdn.com/ricom/archive/2004/01/14/58703.aspx

    The primary purpose of inlining is for trivial property getters & setters.  When it gets much more complex than that you probably don't get inlining.  Also, declaring a method as virtual definitely prevents it from being inlined.

    As for figuring out exactly what gets inlined, that's quite difficult because inlining is handled by the JIT compiler at runtime so even ILDASM won't help you.  I'm not aware that inlining decisions are exposed or recorded in any way, either.  You could use Visual Studio to break into the application after the methods in question have been JIT-compiled and then look at the assembly, but you'd need to turn off debug mode for realistic results.

    Perhaps it's faster to just try separate and embedded methods and benchmark each case...
    • Edited by Christoph Nahr Monday, June 30, 2008 7:34 AM Spelling
    • Marked as answer by pdev.mich Monday, June 30, 2008 8:55 AM
    • Marked as answer by pdev.mich Monday, June 30, 2008 8:55 AM
    • Marked as answer by pdev.mich Monday, June 30, 2008 8:55 AM
    Monday, June 30, 2008 7:33 AM
  • Chris, thanks for your reply.  I've been reading a good bit on this subject already, and you're right.  The most straight forward approach is to figure out where performance could be improved by inlining, and manually embed the code there.  That sure does hurt readability and maintainability though.  Because of this I've formed a nutty plan.

    For good or bad, I'm going to write a simple IL post-processor that will do inlining for me.  It'll look for methods marked with a custom attribute and then inline those functions where they're called.  If anyone is interested in this solution, I'll post it on the net (codeproject?) and post a link here.  Although, I doubt many people have a real reason for forcing inlining.

    If anyone else has more input I'd be happy to hear it.


    Monday, June 30, 2008 9:12 AM
  • I'm not trying to be rude, but what makes you think that your decision whether to inline a particular method is better than the JIT's decision?  The heuristics used by the JIT improve all the time (theoretically at least), while your decision will be static.  Before you start developing your own custom IL post-processing framework, test your code to see whether you really need to perform these 3-rd tier optimizations.
    Sasha Goldshtein | http://blogs.microsoft.co.il/blogs/sasha
    Monday, June 30, 2008 6:20 PM
  • I am a little late but check the link below and download the free chapter from Krzysztof Cwalina and Brad Abram's book go to Classes and Structs, it says structs should be 16bytes or less if not use Generics, Rico and Richter are part of the conversation so maybe his advise on 32bytes is old.


    http://visualstudiomagazine.com/books/






    Asp.net MVP, MCPD Web C#, MCITP BI & MCTS SQL Server 2005
    Monday, June 30, 2008 6:28 PM
    Moderator
  • Sasha, you make one good point.  Before anyone should embark on such a task, they should be sure it will improve performance for them.  Now with that said, I had already ran tests and seen a noteworthy improvement.  This is a good area for me to optimize, and .Net apparently isn't doing it for me now.  Will they do it in the future?  I don't really care about that.  I'd rather have my program work now than to have it work better in 10 years.
    Monday, June 30, 2008 7:56 PM
  • The new service pack for .NET 3.5 will enable to inline struct methods on 32 bits (http://blogs.msdn.com/vancem/archive/2008/05/12/what-s-coming-in-net-runtime-performance-in-version-v3-5-sp1.aspx). The 64 bit JITer can do it already. If you cannot pay a function call then one or all points below apply:

    a) You use the wrong tool for the task at hand
         - Switch to managed C++ and keep the high performance sensitive code native assembler code.

    b) You optimize at the wrong level. There are for sure some algorithmic changes possible that give you much bigger speed gains than to eliminate function calls.

    Yours,
      Alois Kraus

    Monday, June 30, 2008 10:47 PM
  • These comments questioning the OP's approach are not helpful.  He clearly has some idea what he's doing, and you don't know anything about the algorithms he's using.  Yeah, switching to C++ for the critical sections might be a good idea but it's also a lot of work if you're not already familiar with the language.

    As for the usefulness of method inlining: if it were generally useless then the JITer wouldn't bother doing it at all, right?  Ultimately the OP is the only one who knows how this particular code responds to optimization, and the current level of JIT optimization is hardly beyond possibility of improvement.  It's still lagging quite far behind modern Java VMs (which do speculative inlining of virtual methods and dynamically re-optimize frequently called code), let alone optimizing C++ compilers.  And I don't think the extra optimizations provided by these compilers are just useless pranks, either...
    • Edited by Christoph Nahr Tuesday, July 1, 2008 9:30 AM Reformulation
    Tuesday, July 1, 2008 7:35 AM
  • Yes you can optimize function calls to gain a few % overal speed. But try this:

        [MethodImpl(MethodImplOptions.NoInlining)]  
            string UseFulFunc()  
            {  
                var ints = new int[5];  
                ints[ints.Length - 1] = 100;  
                return "Constant";  
            } 

    A simple function with return "something" can be called

    Not Inlined:   230 million calls/s
    Inlined:      2122 million calls/s

    A function which allocates 5 integers and returns a string:
    Not inlined: 61 million calls/s
    Inlined:       62 million calls/s

    To turn it the other way around. If you can spare in your highly optimized code 5 integer allocations you can call 4 other not inlined functions for free. This is still a very conservative assumption. When you deal with video streaming or 3D rendering you have hundreds of megabytes floating around. It is very difficult to find out if you have too many copies of the current frame lurking around because some function did copy a your byte array to do some modifications with it.

    Tuesday, July 1, 2008 12:43 PM