5 ms·
This is cool! A lot of use of SIMD is working on a large array. How does the bounds checking not make this prohibitively expensive? Also, how are the alignment
by ridiculous_fish 11y ago
This is cool! A lot of use of SIMD is working on a large array. How does the bounds checking not make this prohibitively expensive? Also, how are the alignment requirements managed?
- dbaupp 11y agoThere 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