2 ms·
There is the `load` method on SIMD types, e.g. [1]. This does an unaligned load from any place within an array, with bounds checks, i.e. the safest always-works
by dbaupp 11y ago
There is the `load` method on SIMD types, e.g. [1]. This does an unaligned load from any place within an array, with bounds checks, i.e. the safest always-works method.
The bounds checking isn't that bad in and of itself, e.g. for f32x4 it is one bounds check for 4 elements and that bounds check is just a comparison and an extremely well-predicted branch. However, it definitely can be noticable and can inhibit other optimisations.
There's various routes this can be improved for sure, e.g.
- `unsafe` versions of the `load` that don't bounds-check and/or do aligned loads,
- functions that convert a `&[f32]` into a `&[f32x4]` (possibly with prefix and suffix &[f32]'s for unaligned left-overs),
- tweaking the set of optimisation passes the compiler runs to handle the patterns that occur in Rust better (I believe rustc just runs the default set of LLVM passes, which are likely more tuned to C/C++ than Rust, e.g. the IRCE pass[2] should help eliminate more bounds checks but isn't enabled by default because presumably C/C++ don't use bounds checks enough for it to be worth it)
- higher-level combinators/"algorithms" that avoid the need to do the loading/memory-management manually
[1]: http://huonw.github.io/simd/simd/struct.f32x4.html#method.load http://huonw.github.io/simd/simd/struct.f32x4.html#method.lo...
[2]: https://github.com/rust-lang/rust/issues/22987 https://github.com/rust-lang/rust/issues/22987