CodeBlanks Logo Icon CodeBlanks

Summary - SIMD

Combine Simd<T, N> and Mask to build a vector sum.

SIMD summary

SIMD processes several lanes with one instruction. std::simd (Simd<T, N>, masks, reduce_*) is portable but nightly; the stable options are std::arch and auto-vectorization. Vertical operations are lane-wise, horizontal ones reduce the lanes. Mask + select give branchless conditions. For auto-vectorization: access without bounds checks, multiple accumulators, a branchless body; for wider vectors, target-cpu or #[target_feature].

Dot product with four accumulators

Vertical multiply-add, a single horizontal reduction at the end, and the leftovers handled separately:

fn nokta4(a: &[f32], b: &[f32]) -> f32 {
    assert_eq!(a.len(), b.len());
    let mut birikim = [0.0f32; 4];
    for (x, y) in a.chunks_exact(4).zip(b.chunks_exact(4)) {
        for i in 0..4 { birikim[i] += x[i] * y[i]; }
    }
    let n = a.len() / 4 * 4;
    let kalan: f32 = a[n..].iter().zip(&b[n..]).map(|(x, y)| x * y).sum();
    birikim.iter().sum::<f32>() + kalan
}

Practice Fast dot product

Write the nokta4 function above. Let a be the numbers 1 to 10 (f32) and b ten 1.0s; print the result.

Starter code

main.rs
fn main() {
    // buraya yaz
}

Sample solution

main.rs
fn nokta4(a: &[f32], b: &[f32]) -> f32 {
    assert_eq!(a.len(), b.len());
    let mut birikim = [0.0f32; 4];
    for (x, y) in a.chunks_exact(4).zip(b.chunks_exact(4)) {
        for i in 0..4 {
            birikim[i] += x[i] * y[i];
        }
    }
    let n = a.len() / 4 * 4;
    let kalan: f32 = a[n..].iter().zip(&b[n..]).map(|(x, y)| x * y).sum();
    birikim.iter().sum::<f32>() + kalan
}

fn main() {
    let a: Vec<f32> = (1..=10).map(|x| x as f32).collect();
    let b = vec![1.0f32; 10];
    println!("{}", nokta4(&a, &b));
}

Expected output

55

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Why are 4 separate accumulators fast in a dot product?

  • It uses less memory
  • It's more accurate
  • It isn't fast
  • Independent chains progress at once and map directly onto a 4-lane vector Correct answer

Explanation: With a single accumulator each addition waits for the previous one; four accumulators hide the latency.

2 Pair the pieces

Question
for (x, y) in a.chunks_exact(4).____(b.chunks_exact(4)) {
    for i in 0..4 { birikim[i] += x[i] * y[i]; }
}
Answer
for (x, y) in a.chunks_exact(4).zip(b.chunks_exact(4)) {
    for i in 0..4 { birikim[i] += x[i] * y[i]; }
}

Explanation: zip pairs the pieces of two slices at the same position.

3 Group summary

Term Meaning
Simd<T, N> N-lane vector
Mask + select Branchless condition
reduce_sum Horizontal sum
Multiple accumulators Vectorization friendly

All lessons in Expert