Fearless SIMD balances performance with portability
1 Sep 22 8:10 AM · 1d ago · 3 posts · 2 sources · development 1 of 1
The library provides both precise variants (identical across platforms) and fast variants (platform-dependent) for operations with different edge-case behavior. It enables algorithms to leverage hardware's native vector size while also supporting fixed vector sizes, and allows safe fallback to platform intrinsics with no overhead when portable abstractions are insufficient.
“A common criticism leveled at portable SIMD abstractions is that they aren't performant enough, so we've put a lot of effort into making sure that Fearless SIMD never holds you back.”
Fearless SIMD developersFearless SIMD project Library developerLinebender Host/publisher
The whole story posts the bright band is this development · numbered dots are the others · click one to jump
What people said 9 voices · verbatim
-
For context, fearless_simd works by creating implementations of the `Simd` trait for different SIMD levels, and then your function gets invoked as `double_u32s(Avx512, values)` or similar, using a different type for [AVX-512](https://docs.rs/fearless_simd/1.0.0/fearless_simd/struct.Avx512.html) vs…
-
I was checking the docs on Crates.io, and the usage doesn't seem straightforward. 3 things stand out; I'm not a Rust expert, so forgive me if the answers are obvious. The first example has this code: ``` #[simd] fn double_u32s(_: S, values: &mut [u32]) { for value in values { *value = *value * 2; } } ``` Which takes an unused SIMD parameter; what…
-
Such a type doesn't tell you what SIMD instructions are available on the current machine, just what data widths you want to operate on. fearless_simd does in fact have types like this, albeit they don't make the width a generic parameter because const generics in rust kinda suck at the moment, so the types are `u8x16`, `u16x32` and so on. The…
-
Hmm interesting! It doesn't handle any scalable SIMD architectures (aarch64 SVE or riscv's vector extension) which are far more challenging from an API point of view so I’d be interested to see how it handles those challenges (or if it can). It’s also a little unclear to me when the function dispatching happens?…
-
Yeah fair enough, it sounds like you’re in a situation where you know you have high loop counts where I agree that this is an effective solution, and those overheads can easily be amortised. I guess I was thinking more about situations like strlen where the loop counts is very unknown and balancing performance of small loop counts and high loop…
-
What if there were a SIMD type parameterised over type and length, with all SIMD operations defined on this type? `double_u32s` could just take this type and operate on it. This is close to how [SIMD in Mojo works](https://mojolang.org/nightly/docs/std/simd/SIMD/). It does mean that you need to write infra code to specialise to the best SIMD…
-
> In the case of strlen, though, aren't you paying an indirect call anyway? Not necessarily, sometimes the [compiler inlines libc calls](https://godbolt.org/z/5n3P6M7hd). Though admittedly, not for strlen in my experience, so not a great example, sorry. And there are ifunc's for a lot of GLIBC functions, so clearly indirect calls are worth it in…
-
It's actual runtime dispatch. Inside the `dispatch!` macro there's effectively a `match` on the detected SIMD level, with each arm calling the right specialized impl. This isn't exposed in the public API, so fearless_simd could technically switch up the dispatch strategy later. But yes, there's definitely a small overhead for the runtime dispatch…
-
> I guess I was thinking more about situations like strlen In the case of strlen, though, aren't you paying an indirect call anyway? Most of this: > It nearly always means at least an indirect function call, you lose any function inlining or outlining benefits, and the code size increase can hurt performance as you get worse cache locality. will…
All 1 developments of Fearless SIMD v1.0 launches with safe, performant Rust… →
LobstersHacker News