Skip to main content

Crate wide

Crate wide 

Source
Expand description

A crate to help you go wide.

This crate provides SIMD-compatible data types.

When possible, explicit SIMD is used with all the math operations here. As a fallback, the fact that all the lengths of a fixed length array are doing the same thing will often make LLVM notice that it should use SIMD instructions to complete the task. In the worst case, the code just becomes totally scalar (though the math is still correct, at least).

§Masks

SIMD vector masks are per-element booleans, and are represented by SIMD vectors where each element’s value in bits is either all zeros (false) or all ones (true).

SIMD versions of functions that regularly return bool return masks. For example, f32::is_sign_positive returns bool, and f32x4::is_sign_positive returns an f32x4 that represents a mask. The select method can be used to perform a per-element if statement over a mask. For example, for this simple scalar code:

let x = 1.0_f32;

let result = if x.is_sign_positive() {
    5.0
} else {
    3.0
};

assert_eq!(result, 5.0);

This is the SIMD version:

let x = f32x4::new([1.0, -1.0, -1.0, 1.0]);

let result = x.is_sign_positive().select(
    f32x4::splat(5.0),
    f32x4::splat(3.0),
);

assert_eq!(result, f32x4::new([5.0, 3.0, 3.0, 5.0]));

§NaN bit patterns

Operations on SIMD vectors of floats do not make any guarantees about the specific bit-patterns of output NaN values (meaning the sign bit, quiet/signaling bit, and payload). This is unlike standard library operations on float primitives, which do define rules for what NaN bit patterns are returned.

The reason for this is that enforcing guarantees would add substantial overhead to operations, and is generally not worth it.

§Wrapping semantics

SIMD vectors of integers treat operators as wrapping, as if Wrapping<T> was used. Thus, SIMD vectors do not implement wrapping_* functions, because that is the default behavior. This means there are no overflow checks, even in debug builds.

The reason for this is that for most applications where SIMD is appropriate, it is “not a bug” to wrap, and even debug builds are unlikely to tolerate the loss of performance.

This “no panicking” approach extends to more than just integer overflows. It is also true for things like f32x4::clamp. Even though f32::clamp panics for invalid inputs, the SIMD version does not, because it may be used with per-element branching, where invalid elements get discarded later by select.

§Casting

The SIMD types implement the bytemuck::Pod trait, which means that it is possible to do bitwise casts between SIMD types of the same size with the bytemuck::cast() function and others. bytemuck is re-exported by this crate for convenience.

This typically does not have much, if any, runtime overhead in optimized builds.

§Feature flags

  • std: This causes the feature to link to std.
    • Currently this just improves the performance of sqrt when an explicit SIMD sqrt isn’t available.

Re-exports§

pub use bytemuck;

Structs§

f32x4
A SIMD vector with four elements of type f32.
f32x8
A SIMD vector with eight elements of type f32.
f32x16
A SIMD vector with 16 elements of type f32.
f64x2
A SIMD vector with two elements of type f64.
f64x4
A SIMD vector with four elements of type f64.
f64x8
A SIMD vector with eight elements of type f64.
i8x16
A SIMD vector with 16 elements of type i8.
i8x32
A SIMD vector with 32 elements of type i8.
i16x8
A SIMD vector with eight elements of type i16.
i16x16
A SIMD vector with 16 elements of type i16.
i16x32
A SIMD vector with 32 elements of type i16.
i32x4
A SIMD vector with four elements of type i32.
i32x8
A SIMD vector with eight elements of type i32.
i32x16
A SIMD vector with 16 elements of type i32.
i64x2
A SIMD vector with two elements of type i64.
i64x4
A SIMD vector with four elements of type i64.
i64x8
A SIMD vector with eight elements of type i64.
u8x16
A SIMD vector with 16 elements of type u8.
u8x32
A SIMD vector with 32 elements of type u8.
u16x8
A SIMD vector with eight elements of type u16.
u16x16
A SIMD vector with 16 elements of type u16.
u16x32
A SIMD vector with 32 elements of type u16.
u32x4
A SIMD vector with four elements of type u32.
u32x8
A SIMD vector with eight elements of type u32.
u32x16
A SIMD vector with 16 elements of type u32.
u64x2
A SIMD vector with two elements of type u64.
u64x4
A SIMD vector with four elements of type u64.
u64x8
A SIMD vector with eight elements of type u64.

Traits§

AlignTo
A trait for SIMD variants of align_to functions.
CmpEqDeprecated
A deprecated trait for the simd_eq function.
CmpGeDeprecated
A deprecated trait for the simd_ge function.
CmpGtDeprecated
A deprecated trait for the simd_gt function.
CmpLeDeprecated
A deprecated trait for the simd_le function.
CmpLtDeprecated
A deprecated trait for the simd_lt function.
CmpNeDeprecated
A deprecated trait for the simd_ne function.