Find a file
Jacob Lifshay d9a7c40fa0
Merge pull request #502 from folkertdev/miri-nextest
use `cargo miri nextest` to parallelize miri tests
2026-01-26 19:13:43 -08:00
.github experiment with cargo nextest partitions 2026-01-27 00:18:16 +01:00
crates use intrinsics::simd::simd_splat 2026-01-26 20:46:40 +01:00
.gitignore Add script for syncing subtree 2025-01-18 15:33:50 -05:00
beginners-guide.md Fix grammar in beginners-guide.md 2025-04-07 18:13:32 +02:00
Cargo.lock Check some float ops approximately 2025-08-18 01:37:12 -04:00
Cargo.toml Build test dependencies with optimization 2024-08-10 00:47:08 -04:00
CONTRIBUTING.md Update CONTRIBUTING.md for the fact that Travis is no longer used 2021-11-14 12:41:16 -05:00
Cross.toml Reduce proptest iterations 2024-08-08 21:14:37 -04:00
LICENSE-APACHE Add licenses and update Cargo.toml 2020-10-01 23:42:10 -04:00
LICENSE-MIT Add licenses and update Cargo.toml 2020-10-01 23:42:10 -04:00
README.md Update README.md 2022-10-29 21:39:08 -04:00
rust-toolchain.toml use intrinsics::simd::simd_splat 2026-01-26 20:46:40 +01:00
subtree-sync.sh Add script for syncing subtree 2025-01-18 15:33:50 -05:00

The Rust standard library's portable SIMD API

Build Status

Code repository for the Portable SIMD Project Group. Please refer to CONTRIBUTING.md for our contributing guidelines.

The docs for this crate are published from the main branch. You can read them here.

If you have questions about SIMD, we have begun writing a guide. We can also be found on Zulip.

If you are interested in support for a specific architecture, you may want stdarch instead.

Hello World

Now we're gonna dip our toes into this world with a small SIMD "Hello, World!" example. Make sure your compiler is up to date and using nightly. We can do that by running

rustup update -- nightly

or by setting up rustup default nightly or else with cargo +nightly {build,test,run}. After updating, run

cargo new hellosimd

to create a new crate. Finally write this in src/main.rs:

#![feature(portable_simd)]
use std::simd::f32x4;
fn main() {
    let a = f32x4::splat(10.0);
    let b = f32x4::from_array([1.0, 2.0, 3.0, 4.0]);
    println!("{:?}", a + b);
}

Explanation: We construct our SIMD vectors with methods like splat or from_array. Next, we can use operators like + on them, and the appropriate SIMD instructions will be carried out. When we run cargo run you should get [11.0, 12.0, 13.0, 14.0].

Supported vectors

Currently, vectors may have up to 64 elements, but aliases are provided only up to 512-bit vectors.

Depending on the size of the primitive type, the number of lanes the vector will have varies. For example, 128-bit vectors have four f32 lanes and two f64 lanes.

The supported element types are as follows:

  • Floating Point: f32, f64
  • Signed Integers: i8, i16, i32, i64, isize (i128 excluded)
  • Unsigned Integers: u8, u16, u32, u64, usize (u128 excluded)
  • Pointers: *const T and *mut T (zero-sized metadata only)
  • Masks: 8-bit, 16-bit, 32-bit, 64-bit, and usize-sized masks

Floating point, signed integers, unsigned integers, and pointers are the primitive types you're already used to. The mask types have elements that are "truthy" values, like bool, but have an unspecified layout because different architectures prefer different layouts for mask types.