Search code examples
c#vectorization

System.Numerics.Vector<T> or System.Runtime.Intrinsics.Vector128<T>


The documentation for both Vector and Vector128 structs are really similar and there is an AsVector/AsVector128 method to switch between them. However, is there a case where I should use one over the other one?

I looked at the implementation of these two structures and I noticed optimization attributes for JIT in addition for vectors128. Does this mean that only Vector128 is optimized (for specific architecture)? Is it supported under all platforms? So is there a case where the use of Vector128 would cause a NotSupportedException? Or I'm completely wrong and Vectors is just an old structure from the pre net Core 3.0 ?


Solution

  • The System.Numerics.Vector<T> is intended to use whatever vector length is available on the platform, including if no SIMD available at all.

    System.Runtime.Intrinsics.Vector128<T> on the other hand has a fixed number of bits, and that may allow you optimize your code better than the compiler can. It also includes platform specific methods to enable further optimizations. This may not work if the platform does not support a specific vector width. In theory the compiler could reduce the vector width, or issue scalar code if the specific width is not available, but I'm not sure if it does so. 128 bits tend to be the "standard" SIMD width, so should be a fairly safe option.

    Hardware Intrinsics in .NET Core compares the performance of Vector<T> with the intrinsic variants. It suggest summing numbers using intrinsics is about 3 times faster, but the article is quite old, so your results may vary.

    In conclusion, there are use cases for each option, but if you really want to know what option is fastest for your particular use case you might need to write your own benchmark comparing them.