std::simd
- Rust course
- Expert
- Lesson 19/46
- 4 min
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.
Practice 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 {:?}.
Starter code
fn main() {
// buraya yaz
}Sample 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]));
}Expected output
[6.0, 8.0, 10.0, 12.0]
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 For which kind of work does SIMD gain the most?
- Work where the same operation is applied to every element of large arrays Correct answer
- Highly branching code
- Network I/O
- Single-value computation
Explanation: Image processing, audio, matrix multiplication and text search (memchr) are typical examples.
2 Build the array
fn topla4(a: [f32; 4], b: [f32; 4]) -> [f32; 4] {
std::array::____(|i| a[i] + b[i])
}
fn topla4(a: [f32; 4], b: [f32; 4]) -> [f32; 4] {
std::array::from_fn(|i| a[i] + b[i])
}
Explanation: array::from_fn calls the closure for each index and produces an array.
3 Concept and meaning
| Term | Meaning |
|---|---|
SIMD |
Single instruction, multiple data |
lane |
A single element in the vector |
f32x4 |
A 4-lane f32 vector |
portable_simd |
A nightly feature |