Expand description
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 create a function which SIMD and can be multiversioned, it will have a signature like:
use fearless_simd::{Simd, simd_dispatch};
#[inline(always)]
fn sigmoid_impl<S: Simd>(simd: S, x: &[f32], out: &mut [f32]) { /* ... */ }
simd_dispatch!(sigmoid(level, x: &[f32], out: &mut [f32]) = sigmoid_impl);
A few things to note:
- This is generic over any
Simd
type. - The
simd_dispatch
macro is used to create a multi-versioned version of the given function. - The
_impl
suffix is used by convention to indicate the version of a function which will be dispatched to. - The
impl
function must be#[inline(always)]
. The performance of the SIMD implementation will be poor if that isn’t the case. See the section on inlining for details
The signature of the generated function will be:
use fearless_simd::Level;
fn sigmoid(level: Level, x: &[f32], out: &mut [f32]) { /* ... */ }
The first parameter to this function 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 (generated) sigmoid
function to dispatch to the most optimal variant of the 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.
This is required because in LLVM, functions with different target features cannot.
§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.
§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).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
.
Modules§
- core_
arch - Access to architecture-specific intrinsics.
- generated 🔒
- A module containing generated files
- impl_
macros 🔒 - Macros used by implementations
- macros 🔒
- Macros publicly exported
- traits 🔒
- x86
- Implementations of
Simd
on x86 architectures (both 32 and 64 bit).
Macros§
Structs§
- Avx2
- The SIMD token for the “AVX2” and “FMA” level.
- Fallback
- The SIMD token for the “fallback” level.
- Sse4_2
- The SIMD token for the “SSE 4.2” level.
- f32x4
- f32x8
- f32x16
- f64x2
- f64x4
- f64x8
- i8x16
- i8x32
- i8x64
- i16x8
- i16x16
- i16x32
- i32x4
- i32x8
- i32x16
- mask8x16
- mask8x32
- mask8x64
- mask16x8
- mask16x16
- mask16x32
- mask32x4
- mask32x8
- mask32x16
- mask64x2
- mask64x4
- mask64x8
- u8x16
- u8x32
- u8x64
- u16x8
- u16x16
- u16x32
- u32x4
- u32x8
- u32x16
Enums§
- Level
- The level enum with the specific SIMD capabilities available.
Traits§
- Bytes
- Select
- Simd
- TODO: docstring
- Simd
Base - Simd
CvtFloat - Construction of floating point vectors from integers
- Simd
CvtTruncate - Construction of integer vectors from floats by truncation
- Simd
Element - Simd
Float - Simd
From - Value conversion, adding a SIMD blessing.
- SimdInt
- Simd
Into - Value conversion, adding a SIMD blessing.
- Simd
Mask - With
Simd