"SIMD" without the need of specialized types

While stumbling over Mojo I noticed that they represent every primitive type as an array of one element. With primitive arrays of fixed length automatically being handled as simd type (at least I think so, might also be just good auto vectorization)

Which got me thinking if its possible to implement all basic math operations like addition, subtraction etc. for example the trait Add on [T; N] where T is also Add and N is power of two 2, 4, 8 and let the compiler replace it with a simd operation if possible and appropriate?

While this is basically the way that nightly repr(simd) "portable simd" works, the main issues with doing so for any appropriately sized [iN; M] is 1) the alignment requirements of vector data is stricter than just that of the array, and 2) when you only have one SIMD vector's worth of data, often its actually better to just do the scalar operations due to the (minor but present) extra costs of using SIMD operations.

The alternative which Rust has had since forever is auto-vectorization. If you write code that can be broadcast straightforwardly over multiple SIMD lanes, LLVM is usually quite good at replacing loops with scalar operations with loops doing vector operations.

4 Likes

For simple things like [f32; 4], the compiler in fact already does that:

But arrays and simd vectors have different preferred alignments, so if you're storing them you want a different type. And that's where Simd in std::simd - Rust comes in -- which has Add implemented, and you can convert arrays into if you want.

4 Likes