Friday, August 1, 2008

Structure Inlining with .Net 3.5 SP1

I just stumbled on a fascinating performance improvement coming up in .Net 3.5 SP1.

When working with value types (structs) the JIT currently hits the stack each time you access a field - which is quite inefficient.

In SP1 they've added an algorithm called "value type scalar replacement"; which intuitively does exactly what it sounds like!

Take the following code:
static int MyMethod1(int v)
{
Point point; // gets a stack location.

// All 3 field accesses involve stack operations.
point.x = v;
point.y = v * 2;

return point.x;
}

The JIT will replace the value type (Point is a struct) with scalars:
static int MyMethod2(int v)
{
int x; int y; // Was “struct point;”. Now replaced by x and y.
x = v;
y = v * 2;

return x;
}

After the JIT inlines the structure, it can optimise the routine by placing the integers on the register rather than the stack.

What's the difference?

We are roughly looking at a 10x improvement! (Using a quick and dodgy test app)

This is fantastic, especially when dealing with lots of structs like points and rectangles etc.

What's the catch?

This isn't magically going to work on all your value types; there are strict guidelines when this replacement can occur:

- The value type must have no more than 4 fields

- These fields must be value types, or object references

- You must use [StructLayout(LayoutKind.Sequential)], which is the default anyhow.


There some other catches, but if you are creating complicated structures, you really should think about making them a class.

More Improvements

This is just a snippet of the algorithm, whereas the original article explains it in much more detail.

BTW: This is in the CLR, so all .Net languages benefit! And of course this includes F# and FParsec.

Cheers to SP1!

No comments: