Rust
std::simd
Get started with packed operations via std::simd.
std::simd
SIMD (single instruction, multiple data) processes several values at once with a single processor instruction: like adding 4 or 8 f32s in one go. Rust has the std::simd module for portable SIMD, but it's still on nightly (#![feature(portable_simd)]):
#![feature(portable_simd)]
use std::simd::f32x4;
let a = f32x4::from_array([1.0, 2.0, 3.0, 4.0]);
let b = f32x4::from_array([5.0, 6.0, 7.0, 8.0]);
let c = a + b; // a single instruction: [6, 8, 10, 12]
Stable Rust uses std::arch (platform-specific instructions) and the compiler's auto-vectorization. In the exercises we'll build lane logic with fixed-size arrays.
Lane-wise operation
SIMD operations are lane-wise: the i-th result depends only on the i-th elements of the inputs. Writing the same logic with arrays gives the compiler a clean pattern for vectorization:
fn topla4(a: [f32; 4], b: [f32; 4]) -> [f32; 4] {
std::array::from_fn(|i| a[i] + b[i])
}
std::array::from_fn builds a fixed-size array by calling a closure for each index; in a release build this usually becomes a single SIMD add instruction.
Exercise Four-lane addition
Write the topla4 function above. Print the result for [1.0, 2.0, 3.0, 4.0] and [5.0, 6.0, 7.0, 8.0] with {:?}.
Show example solution
fn topla4(a: [f32; 4], b: [f32; 4]) -> [f32; 4] {
std::array::from_fn(|i| a[i] + b[i])
}
fn main() {
println!("{:?}", topla4([1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0]));
}
Test yourself
-
For which kind of work does SIMD gain the most?
- Work where the same operation is applied to every element of large arrays
- Highly branching code
- Network I/O
- Single-value computation
Show answer
Work where the same operation is applied to every element of large arrays — Image processing, audio, matrix multiplication and text search (memchr) are typical examples.
-
Build the array
fn topla4(a: [f32; 4], b: [f32; 4]) -> [f32; 4] {
std::array::____(|i| a[i] + b[i])
}
Show answer
fn topla4(a: [f32; 4], b: [f32; 4]) -> [f32; 4] {
std::array::from_fn(|i| a[i] + b[i])
}
-
Concept and meaning
- SIMD
- Single instruction, multiple data
- lane
- A single element in the vector
- f32x4
- A 4-lane f32 vector
- portable_simd
- A nightly feature
Next lesson: Simd<T, N>