Earlier quoted context omitted.
.NET's standard library is very heavily vectorized, vectorization is considered in all scenarios where it is applicable, the compiler will also apply it to copies of known length and string comparisons fully eliding and unrolling Memmove and SequenceEqual calls. The gives languages that run on top of .NET massive performance advantage in a variety of scenarios versus any other language - C++ and Rust stdlibs are far…
Rust has had a stable SIMD vector API[1] for a long time. But, it's architecture specific. The portable API[2] isn't stable yet, but you probably can't use the portable API for some of the more exotic uses of SIMD anyway. Indeed, that's true in .NET's case too[3]. So .NET has to rely on "manually vectorized with intrisics for each individual platform" as well. Rust does all this SIMD too. It just isn't in the standar…
Indeed, I meant to say "portable SIMD API" but it got lost somewhere in the stream of consciousness - sorry.
As for limitations of using such APIs in the standard library - in case of .NET platform-specific paths mainly exist for the following reasons:
- To achieve optimal codegen with more specific instructions
- To account for platform differences that are not expressible through crossplat vectors (vpternlog on x86, tbl/tbx on Aarch64)
- The code was written before crossplat API was available and has not been updated yet
Another aspect of such API is that all intrinsics still consume the same unified group of Vector128/256/512 so that writing scenario-specific helper is still relatively easy, which is what bits of standard library often opt into.