#[non_exhaustive]pub enum Level {
Fallback(Fallback),
Sse4_2(Sse4_2),
Avx2(Avx2),
}Expand description
The level enum with the specific SIMD capabilities available.
The contained values serve as a proof that the associated target feature is available.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Fallback(Fallback)
Scalar fallback level, i.e. no supported SIMD features are to be used.
This can be created with Level::fallback.
Sse4_2(Sse4_2)
The SSE4.2 instruction set on (32 and 64 bit) x86.
Avx2(Avx2)
The AVX2 and FMA instruction set on (32 and 64 bit) x86.
Implementations§
Source§impl Level
impl Level
Sourcepub fn new() -> Self
Available on crate feature std or WebAssembly only.
pub fn new() -> Self
std or WebAssembly only.Detect the available features on the current CPU, and returns the best level.
If no SIMD instruction set is available, a scalar fallback will be used instead.
This function requires the standard library, to use the
is_x86_feature_detected
or is_aarch64_feature_detected.
If you are on wasm32, you can use Level::new_wasm instead.
Note that in most cases, this function should only be called by end-user applications.
Libraries should instead accept a Level argument, probably as they are
creating their data structures, then storing the level for any computations.
Libraries which wish to abstract away SIMD usage for their common-case clients,
should make their non-Level entrypoint match this function’s cfg; to instead
handle this at runtime, they can use try_detect,
handling the None case as they deem fit (probably panicking).
This strategy avoids users of the library inadvertently using the fallback level,
even if the requisite target features are available.
If you are on an embedded device where these macros are not supported, you should construct the relevant variants yourself, using whatever way your specific chip supports accessing the current level.
This value will be passed to functions generated using simd_dispatch.
Examples found in repository?
More examples
Sourcepub fn try_detect() -> Option<Self>
pub fn try_detect() -> Option<Self>
Get the target feature level suitable for this run.
Should be used in libraries if they wish to handle the case where
target features cannot be detected at runtime.
Most users should prefer new.
This is discussed in more detail in new’s documentation.
Sourcepub fn as_sse4_2(self) -> Option<Sse4_2>
Available on x86 or x86-64 only.
pub fn as_sse4_2(self) -> Option<Sse4_2>
If this is a proof that SSE4.2 (or better) is available, access that instruction set.
This method should be preferred over matching against the Sse4_2 variant of self,
because if Fearless SIMD gets support for an instruction set which is a superset of SSE4.2,
this method will return a value even if that “better” instruction set is available.
This can be used in combination with the safe_wrappers feature to gain checked access to
the level-specific SIMD capabilities.
Sourcepub fn as_avx2(self) -> Option<Avx2>
Available on x86 or x86-64 only.
pub fn as_avx2(self) -> Option<Avx2>
If this is a proof that AVX2 and FMA (or better) is available, access that instruction set.
This method should be preferred over matching against the AVX2 variant of self,
because if Fearless SIMD gets support for an instruction set which is a superset of AVX2,
this method will return a value even if that “better” instruction set is available.
This can be used in combination with the safe_wrappers feature to gain checked access to
the level-specific SIMD capabilities.
Sourcepub fn fallback() -> Self
pub fn fallback() -> Self
Create a scalar fallback level, which uses no SIMD instructions.
This is primarily intended for tests; most users should prefer Level::new.
Sourcepub fn dispatch<W: WithSimd>(self, f: W) -> W::Output
pub fn dispatch<W: WithSimd>(self, f: W) -> W::Output
Dispatch f to a context where the target features which this Level proves are available are enabled.
Most users of Fearless SIMD should prefer to use simd_dispatch to
explicitly vectorize a function. That has a better developer experience
than an implementation of WithSimd, and is less likely to miss a vectorization
opportunity.
This has two use cases:
- To call a manually written implementation of
WithSimd. - To ask the compiler to auto-vectorize scalar code.
For the second case to work, the provided function must be attributed with #[inline(always)].
Note also that any calls that function makes to other functions will likely not be auto-vectorized,
unless they are also #[inline(always)].