macro_rules! dispatch {
($level:expr, $simd:pat => $op:expr) => { ... };
}Expand description
Access the applicable Simd for a given level, and perform an operation using it.
This macro is the root of how any explicitly written SIMD functions in this crate are called from a non-SIMD context.
The first parameter to the macro is the Level.
You should prefer to construct a Level once and pass it around, rather than
frequently calling Level::new().
This is because Level::new has to detect which target features are available, which can be slow.
The code of the operation will be repeated literally several times in the output, so you should prefer
to keep this code small (as it will be type-checked, etc. for each supported SIMD level on your target).
In most cases, it should be a single call to a function which is generic over Simd implementations,
as seen in the examples.
For clarity, it will only be executed once per execution of dispatch.
To guarantee target-feature-specific code generation, any functions called within the operation should
be #[inline(always)].
Note that as an implementation detail of this macro, the operation will be executed inside a closure.
This is what enables the target features to be enabled for the code inside the operation.
A consequence of this is that early return and ? will not work as expected.
Note that in cases where you use dispatch to call a single function (which we expect to be the
majority of cases), you can use ? on the return value of dispatch instead.
To emulate early return, you can use ControlFlow instead.
ยงExample
use fearless_simd::{Level, Simd, dispatch};
#[inline(always)]
fn sigmoid<S: Simd>(simd: S, x: &[f32], out: &mut [f32]) { /* ... */ }
let level = Level::new();
dispatch!(level, simd => sigmoid(simd, &[/*...*/], &mut [/*...*/]));