[−][src]Attribute Macro multiversion::multiversion
#[multiversion]
Provides function multiversioning by explicitly specifying function versions.
Functions are selected in order, calling the first matching target. The function tagged by the attribute is the generic implementation that does not require any specific architecture or features.
This attribute is useful when writing SIMD or other optimized code by hand. If you would like
to rely on the compiler to produce your optimized function versions, try the target_clones
attribute instead.
Safety
Functions compiled with the target_feature
attribute must be marked unsafe, since calling
them on an unsupported CPU results in a crash. To dispatch an unsafe
function version from a
safe function using the multiversion
macro, the unsafe
functions must be tagged as such. The
multiversion
attribute will produce a safe function that calls unsafe
function versions, and
the safety contract is fulfilled as long as your specified targets are correct. If your
function versions are unsafe
for any other reason, you must remember to mark your
multiversioned function unsafe
as well.
Examples
A simple feature-specific function
This example creates a function where_am_i
that prints the detected CPU feature.
use multiversion::multiversion; fn where_am_i_avx() { println!("avx"); } fn where_am_i_sse() { println!("sse"); } fn where_am_i_neon() { println!("neon"); } #[multiversion( "[x86|x86_64]+avx" => where_am_i_avx, "x86+sse" => where_am_i_sse, "[arm|aarch64]+neon" => where_am_i_neon )] fn where_am_i() { println!("generic"); }
Making target_feature
functions safe
This example is the same as the above example, but calls unsafe
specialized functions. Note
that the where_am_i
function is still safe, since we know we are only calling specialized
functions on supported CPUs. In this example, the target
attribute is used for
convenience.
use multiversion::{multiversion, target}; #[target("[x86|x86_64]+avx")] unsafe fn where_am_i_avx() { println!("avx"); } #[target("x86+sse")] unsafe fn where_am_i_sse() { println!("sse"); } #[target("[arm|aarch64]+neon")] unsafe fn where_am_i_neon() { println!("neon"); } #[multiversion( "[x86|x86_64]+avx" => unsafe where_am_i_avx, "x86+sse" => unsafe where_am_i_sse, "[arm|aarch64]+neon" => unsafe where_am_i_neon )] fn where_am_i() { println!("generic"); }
Static dispatching
The multiversion
attribute provides a function that can be statically dispatched. See
static dispatching for more information.