Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET local variable optimization

I was reading through the .NET sources when I found this:

// Constructs a Decimal from an integer value.
//
public Decimal(int value) {
    //  JIT today can't inline methods that contains "starg" opcode.
    //  For more details, see DevDiv Bugs 81184: x86 JIT CQ:
    //  Removing the inline striction of "starg".
    int value_copy = value;  
    if (value_copy >= 0) {
        flags = 0;
    }
    else {
        flags = SignMask;
        value_copy = -value_copy;
    }
    lo = value_copy;
    mid = 0;
    hi = 0;
}

As you can see, the constructor of the Decimal structure copies the method argument to a local variable rather than using it directly. I was wondering what the comment means and how it relates to performance & optimization?

My guess is that once you want to modify the existing argument, method can be no longer inlined?

http://referencesource.microsoft.com/#mscorlib/system/decimal.cs#f9a4da9d6e110054#references

like image 351
Erti-Chris Eelmaa Avatar asked Oct 14 '14 19:10

Erti-Chris Eelmaa


1 Answers

My guess is that once you want to modify the existing argument, method can be no longer inlined?

Short answer: Your guess is correct (if that source code comment is still true today).

//  JIT today can't inline methods that contains "starg" opcode.

"The JIT" is that part of the .NET runtime that translates intermediate language (IL) (i.e. .NET "bytecode") to your computer's assembly language. Only then can code be executed by your computer. The JIT performs this translation method-by-method, and only when actually needed: Whenever a method is first invoked, it is first compiled down to actual assembly language, "just-in-time" (JIT).

The C# compiler does not generate assembly language for your computer's architecture straight away; instead, it generates intermediate language, which is some kind of assembly language for an abstract stack machine (which was defined in the ECMA 334 international standard).

For example, assignments to a parameter (in your example: value) would get translated by the C# compiler to an IL instruction called starg ("store to argument").

The comment basically says that if the method contained such an assignment (value = …), then the JIT would currently not be able to "inline" it. "Inlining a method" means that instead of generating call instructions to a method (i.e. branch commands to a different code location), the JIT would instead insert the method's whole body in the place where it is called. This is usually done to optimize execution speed, because no branch/jump is necessary, and additionally I assume that no new stack frame must be set up, too.

By assigning to a local variable instead (value_copy = …), this limitation of the JIT is circumvented, because assignments to local variables cause a different IL instruction to be generated: stloc ("store to local variable").

See also:

  • Andrey Akinshin: "A story about JIT-x86 inlining and starg" (blog post)
like image 50
stakx - no longer contributing Avatar answered Oct 10 '22 07:10

stakx - no longer contributing