Fearless SIMD v1.0 is here

42 points by ohrv 9 hours ago on lobsters | 7 comments

Shnatsel, September 22, 2026

fearless_simd takes unsafe out of SIMD.

It has come a long way since the original prototype 8 years ago. We are now confident that whatever it is you need, be it just autovectorization and multiversioning, or full-blown portable SIMD abstractions, or safe access to intrinsics and nothing more, Fearless SIMD will serve you well.

Instead of paraphrasing the changelog, I'd like to take this opportunity to reflect on the goals of Fearless SIMD, how it achieves them, and what sets it apart from other SIMD abstractions.

Performance

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.

For example, when implementing portable abstractions for operations with different behavior in edge cases on different platforms, such as swizzles or floating-point maximum, we provide both a precise variant that's the same on all platforms, and a fast variant that returns a platform-dependent result for use when you expect the edge cases to never happen.

We also made it easy to express SIMD algorithms in terms of the hardware's native vector size, so that your code always takes full advantage of the hardware, no matter where it runs. Fixed vector sizes are also supported for algorithms that need them.

We also put a lot of effort into making sure the implementations of our portable SIMD operations are state-of-the-art, and even contributed improvements upstream - both to Rust and LLVM.

But if you need an instruction that isn't covered by portable abstractions, or want even more control, you can safely drop down to platform intrinsics with no overhead for the parts of your code that need it, and keep the rest simple and portable.

Thanks to safe access to intrinsics, there is no performance ceiling.

Safety

If you look up the source code of any other SIMD abstraction, you will find that it is full of unsafe code. Something like rg unsafe will turn up several thousand unsafe blocks.

But not in Fearless SIMD! The crate is carefully engineered not to require ad-hoc unsafe code.

One piece of the puzzle is the kernel! macro, which leans on target feature v1.1 in the compiler to invoke most SIMD intrinsics without unsafe. I have described the design in detail in an earlier blog post, so check this out if you'd like to learn more.

That removes most of the ad-hoc unsafe, but doesn't cover SIMD load/store operations which operate on raw pointers. That's where our safe transmute module, inspired by crates such as bytemuck and zerocopy, comes into play.

SIMD intrinsics like _mm_loadu_epi32 may seem special, but actually turn into plain loads and stores behind the scenes. So you can fully replicate their functionality with a single, reusable wrapper.

Thanks to the power of Rust's type system, we only need to audit these two small, self-contained building blocks. As long as they are memory-safe, the rest of the codebase is guaranteed to be memory-safe as well.

At last, SIMD in Rust can be truly fearless.

Ergonomics

Function multiversioning is tricky.

Previous solutions either require adding #[inline(always)] annotations and understanding their implications, or impose a small overhead on every function call. The latter is fine most of the time, but degrades performance on very small functions, and still requires you to surgically add #[inline(always)] to get around that.

Both are leaky abstractions - you still need to think about what is happening under the hood!

Alongside fearless_simd v1.0, we are launching fearless_simd_macros v0.1, which provides a non-leaky abstraction: the #[simd] macro. With it, you don't have to think about what's happening under the hood at all! Put it on any SIMD function and it Just Works.

That said, while this is a big step forward for the ecosystem, there is still some boilerplate involved. We are keen to reduce it further, either with compiler support via the Struct Target Features RFC to get rid of the #[simd] annotation entirely, or perhaps through other tricks we will explore in the future.

And if you don't like procedural macros, the old way of doing things is still available, if less convenient.

Ergonomics is the one area we expect may still evolve. But this does not compromise the stability guarantees of the core fearless_simd crate, and the code written today with or without the #[simd] macro will continue working indefinitely.

Stability

Fearless SIMD is here to stay. We will be providing 3 years of security updates for v1.0 and all later versions.

While we cannot see the future, there are viable paths to supporting both near-term Rust features, such as the f16 type, and longer-term features such as SVE and RISC-V Vector Extension if/when these hardware extensions become relevant, without API-breaking changes.

Relation to std::simd

We would love to see std::simd stabilized, but it would not make Fearless SIMD obsolete.

The Rust standard library implements only the parts that absolutely have to be in it, and the rest (e.g. multiversioning, hardware-width vectors) is left up to the ecosystem crates.

fearless_simd includes an equivalent of std::simd that works on stable Rust, but that is just one part of a bigger whole.

Once std::simd is stabilized, we will port Fearless SIMD to it to delete a lot of custom code and gain support for all sorts of obscure platforms. But the need for ecosystem crates such as fearless_simd will remain.

Adoption

It doesn't matter how brilliant your crate is if nobody is using it.

Fearless SIMD is already used by 30 other crates as a direct dependency, and is indirectly relied on by over a thousand crates!

It already underpins a nontrivial fraction of the Rust ecosystem, and we hope that v1.0 will take this even further.

If you'd like to use Fearless SIMD in your project, check out the documentation and examples, and feel free to ask questions on Zulip!