Update to SIMD Support

Update to SIMD Support

Rate This
  • Comments 15

A month ago we announced support for SIMD. Today, we're announcing an update to "RyuJIT" and our NuGet package that exposes the SIMD programming model.

Updates to the Microsoft.Bcl.Simd NuGet package

More types for Vector<T>

We've expanded the support of the Vector<T> types:

  • We now support int, long, float, double as well as byte, sbyte, ushort and short.
  • Support for uint, ulong is still coming.

Support for mutable vector types

We've also changed our stance on immutability. In the previous release all types were immutable. The primary reason was that we wanted to discourage element-wise initialization for Vector<T>. For consistency we originally decided to apply immutability to the fixed size vector types (Vector2f, Vector3f and Vector3f).

Based on your feedback we decided to change this. Now it looks as follows:

  • Vector<T> is still immutable as we believe that's the right design due to the way this type works.
  • Vector2f, Vector3f and Vector4f are now mutable. This is primarily done to match the shape of existing vector types, especially from the graphics domain.

This means you can now write code like this:

// Still possible:
Vector3f v = new Vector3f(1f, 2f, 3f);

// Now also possible:
Vector3f w = new Vector3f();
w.X = 1f;
w.Y = 2f;
w.Z = 3f;

Better support for arrays

Vector<T> has support for moving data from and to arrays:

// Array of 2 * Vector<int>.Length values
int[] values = CreateValues();

// Multiply the first N values with the second
// N values (N, being Vector<int>.Length).
Vector<int> x = new Vector<int>(values, 0);
Vector<int> y = new Vector<int>(values, Vector<int>.Length);
Vector<int> z = x * y;

// Store the result in the array where x came from
z.CopyTo(values, 0);

With this update, Vector<T>.CopyTo() is now a JIT intrinsic and will result in a store from the SIMD register right into memory.

Updates to the JIT "RyuJIT"

We've added support for "RyuJIT" for non-Windows 8 machines. If you install the new .NET Framework 4.5.2, you can use "RyuJIT" on Windows Vista, Windows 7, Windows Server 2008, and Windows Server 2012.

You should also take a look at this post on the CLR code gen blog. Kevin Frei is our JIT dev lead and quite an active blogger. This way, you can get the information right from the horse's mouth so to speak.

You can download the updated RyuJIT here.


We've just released an update for SIMD support, which includes an update to "RyuJIT" as well the Microsoft.Bcl.Simd NuGet package. In order to be able to install RyuJIT on a non-Windows 8 machine, you need to install .NET Framework 4.5.2 first.

Please download & play with the bits - we'd love to hear your feedback! For bugs, please send us a mail to ryujit(at)microsoft.com.

Leave a Comment
  • Please add 5 and 8 and type the answer here:
  • Post
  • "Vector2f, Vector3f and Vector4f are now mutable. This is primarily done to match the shape of existing vector types, especially from the graphics domain."


  • This sounds cool. I'm not sure why CopyTo would overwrite x though from the code. Doesn't that mean that x is mutable?

  • I think it is bad decision to make the vector types mutable. Instead support methods should be added for manipulating elements returning new vectors. Making these multi-element value types mutable will just confuse users and generate issues with users not understanding why a vectors element is not updated when it comes from an array and so forth. Classic value type issues.

    Instead consider better "new" methods by adding static constructor methods instead e.g. Vector2f.ByXY(x, y) to be specific about parameter ordering etc.

  • @Ultrahead: You're welcome!

    @MarkAdamson: Sorry, my wording wasn't quite right. What I meant is that z.CopyTo(values, 0) will store the values of z in the values array at the location from which we started to construct x. I've changed the comment to better reflect that. Does this help?

    @harrydev: Mutable value types have a bunch of problems, that's correct. We currently don't expose any methods that mutate the vectors (they all return new values). So it's really only about the component properties (X, Y, Z, W). While I can see your point (that's why we originally had a pure immutable design) the fact remains that virtually all popular representations of vector types have a mutable design...

  • In the example under the heading "Better support for arrays," how many allocations of size values.Length are there and where are they? How many copies are there and where are they?

  • @Curt: The CopyTo() method itself doesn't allocate -- it just copies its data to the array that is passed in. The assumption in the code sample is that the array `values` contains at least `2 * Vector<int>.Length` elements.

    Does that make sense?

  • Along with the mutable fixed vectors you can inmutable versions named Vector2fi an so on so forth.

  • @Immo That helps a bit, thanks. What I am trying to understand is will x have the new values in, or does the Vector<T> constructor make a copy of the array? The second would be logical to me since you say the Vector<T> is still immutable. But perhaps you just mean that the interface of Vector<T> is immutable, and that it's just a wrapper over an array that can be altered.

  • Sorry, I forgot to add the word "define" here: "Along with the mutable fixed vectors you could define immutable versions named Vector2fi an so on so forth."

    I have also posted a suggestion to Roslyn to enforce immutability at compile time on C#:


  • @MarkAdamson: I see what you're saying. Constructing a Vector<T> from an array will perform a copy of the values from the array. At the processor level though, that's simply a SIMD register load from memory. So yes, this means that Vector<T> (and it's values) are fully immutable.

    @Ultrahead: I don't think we'd add additional immutable vector types. We'd rather ship only one design. The language feature is an interesting suggestion. I've responded to this and raised my concerns :-)

  • @Immo: I see and I guess you meant "node" instead of "child" in the GetParent method. Plus, my suggestion was for public fields (not private, as in your example).

    Any comments/concerns about this one? roslyn.codeplex.com/.../543883

  • Hi,

    First of all, having Simd support in .net is just awesome and thanks for that.

    Good Vectorization is a very important but hard aspect of many algorithms implementations (such as machine learning algorithms). A bad implementation can ruin an algorithm performance.

    Many algorithms do use large matrix and having proper fine-tuned matrix computation Apis would be very awesome. Do you plan on supporting higher level computations and data structures such as Matrix in the future?  I found this presentation that shows the performance gain for large matrix multiplications compared to regular implementations www-cs.ccny.cuny.edu/.../Matrix-vector%20multiplication_4.pdf. Having that kind of tool added to .net would be very nice.


  • Things that I miss from this version:

    1. Array constructors for Vector4f

    2. Add a Sum method to the VectorMath class

    3. Support for arbitrary length vectors. Handling this in my code is difficult, since I can't know Vector<float>.Length at design time - so I have to use for-loops. Also I have to duplicate each for-loop to handle the last few, remaining elements. The "new Vector<float>(float[])" constructor is broken b/c the documentation says it works with an arbitrary number elements when it'll only read the first few.

    Other than that, it's totally awesome!

  • My suggestion  is not about SIMD but if you guys rewriting JIT  anyway could you pls add the following optimizations:

    1. Objects types exact equality  comparison  optimized to just comparing typehandle values in objects' headers:

    bool  sameType =  obj1.GetType() == obj2.GetType();

    2. Getting RuntimeTypeHandle's value  optimized to just getting typehandle (possibly just one machine instruction):

    IntPtr typeHandleValue = obj..GetType().TypeHandle.Value;


  • Any chance the exp, log, max and other functions might be supported soon? Exp and Log are pretty critical for numerical computing.

Page 1 of 1 (15 items)