Crate stdsimd [] [src]

SIMD support

This crate provides the fundamentals of supporting SIMD in Rust. This crate should compile on all platforms and provide simd and vendor modules at the top-level. The simd module contains portable vector types which should work across all platforms and be implemented in the most efficient manner possible for the platform at hand. The vendor module contains vendor intrinsics that operate over these SIMD types, typically corresponding to a particular CPU instruction

extern crate stdsimd;
use stdsimd::simd::u32x4;

fn main() {
    let a = u32x4::new(1, 2, 3, 4);
    let b = u32x4::splat(10);
    assert_eq!(a + b, u32x4::new(11, 12, 13, 14));
}

Note: This crate is nightly only at the moment, and requires a nightly rust toolchain to compile.

This documentation is only for one particular architecture, you can find others at:

Portability

The simd module and its types should be portable to all platforms. The runtime characteristics of these types may vary per platform and per CPU feature enabled, but they should always have the most optimized implementation for the target at hand.

The vendor module provides no portability guarantees. The vendor module is per CPU architecture currently and provides intrinsics corresponding to functions for that particular CPU architecture. Note that the functions provided in this module are intended to correspond to CPU instructions and have no runtime support for whether you CPU actually supports the instruction.

CPU target feature detection is done via the cfg_feature_enabled! macro at runtime. This macro will detect at runtime whether the specified feature is available or not, returning true or false depending on the current CPU.

#![feature(cfg_target_feature)]

#[macro_use]
extern crate stdsimd;

fn main() {
    if cfg_feature_enabled!("avx2") {
        println!("avx2 intrinsics will work");
    } else {
        println!("avx2 intrinsics will not work");
        // undefined behavior: may generate a `SIGILL`.
    }
}

After verifying that a specified feature is available, use target_feature to enable a given feature and use the desired intrinsic.

Be careful when using this code, it's not being tested!
// avx2 specific code may be used in this function
#[target_feature = "+avx2"]
fn and_256() {
    // avx2 feature specific intrinsics will work here!
    use stdsimd::vendor::{__m256i, _mm256_and_si256};

    let a = __m256i::splat(5);
    let b = __m256i::splat(3);

    let got = unsafe { _mm256_and_si256(a, b) };

    assert_eq!(got, __m256i::splat(1));
}

Status

This crate is intended for eventual inclusion into the standard library, but some work and experimentation is needed to get there! First and foremost you can help out by kicking the tires on this crate and seeing if it works for your use case! Next up you can help us fill out the vendor intrinsics to ensure that we've got all the SIMD support necessary.

The language support and status of SIMD is also still a little up in the air right now, you may be interested in a few issues along these lines:

Modules

simd

Platform independent SIMD vector types and operations.

vendor

Platform dependent vendor intrinsics.

Macros

cfg_feature_enabled

Is a feature supported by the host CPU?