Fearless SIMD
Safer and easier SIMD
[!CAUTION] Fearless SIMD is in extremely early experimental development. As such, there are no stability guarantees, APIs are incomplete, and architectures have missing implementations. Fearless SIMD is being developed in conjunction with the Vello Sparse Strips renderer.
A helper library to make SIMD more friendly.
Fearless SIMD exposes safe SIMD with ergonomic multi-versioning in Rust.
Fearless SIMD uses "marker values" which serve as proofs of which target features are available on the current CPU.
These each implement the Simd trait, which exposes a core set of SIMD operations which are implemented as
efficiently as possible on each target platform.
Additionally, there are types for packed vectors of a specific width and element type (such as f32x4).
Fearless SIMD does not currently support vectors of less than 128 bits.
These vector types implement some standard arithmetic traits (i.e. they can be added together using
+, multiplied by a scalar using *, among others), which are implemented as efficiently
as possible using SIMD instructions.
These can be created in a SIMD context using the SimdFrom trait, or the
from_slice associated function.
To call a function with the best available target features and get the associated Simd
implementation, use the [dispatch!()] macro:
use ;
// The stored level, which you should only construct once in your application.
let level = new;
dispatch!;
A few things to note:
sigmoidis generic over anySimdtype.- The
dispatchmacro is used to invoke the given function with the target features associated with the suppliedLevel. - The function or closure passed to [
dispatch!()] should be#[inline(always)]. The performance of the SIMD implementation may be poor if that isn't the case. See the section on inlining for details
The first parameter to [dispatch!()] is the Level.
If you are writing an application, you should create this once (using Level::new), and pass it to any function which wants to use SIMD.
This type stores which instruction sets are available for the current process, which is used
in the macro to dispatch to the most optimal variant of the supplied function for this process.
Inlining
Fearless SIMD relies heavily on Rust's inlining support to create functions which have the
given target features enabled.
As such, most functions which you write when using Fearless SIMD should have the #[inline(always)] attribute.
Webassembly
WASM SIMD doesn't have feature detection, and so you need to compile two versions of your bundle for WASM, one with SIMD and one without, then select the appropriate one for your user's browser. TODO: Expand on this.
Credits
This crate was inspired by pulp, std::simd, among others in the Rust ecosystem, though makes many decisions differently.
It benefited from conversations with Luca Versari, though he is not responsible for any of the mistakes or bad decisions.
Feature Flags
The following crate feature flags are available:
std(enabled by default): Get floating point functions from the standard library (likely using your target's libc). Also allows usingLevel::newon all platforms, to detect which target features are enabled.libm: Use floating point implementations from libm.safe_wrappers: Include safe wrappers for (some) target feature specific intrinsics, beyond the basic SIMD operations abstracted on all platforms.
At least one of std and libm is required; std overrides libm.
Minimum supported Rust Version (MSRV)
This version of Fearless SIMD has been verified to compile with Rust 1.86 and later.
Future versions of Fearless SIMD might increase the Rust version requirement. It will not be treated as a breaking change and as such can even happen with small patch releases.
Community
Discussion of Fearless SIMD development happens in the Linebender Zulip, specifically in #simd. All public content can be read without logging in.
Contributions are welcome by pull request. The Rust code of conduct applies.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.