typestar

parallel_sum.rs in Rust

Splitting a big sum across threads, then comparing against the serial answer.

use std::thread;
use std::time::Instant;

fn serial_sum(values: &[u64]) -> u64 {
    values.iter().sum()
}

fn threaded_sum(values: &[u64], workers: usize) -> u64 {
    let chunk = values.len().div_ceil(workers);
    let mut totals = vec![0u64; workers];

    thread::scope(|scope| {
        for (slot, part) in totals.iter_mut().zip(values.chunks(chunk)) {
            scope.spawn(move || {
                *slot = part.iter().sum();
            });
        }
    });

    totals.iter().sum()
}

fn main() {
    let values: Vec<u64> = (1..=2_000_000).collect();

    let started = Instant::now();
    let one = serial_sum(&values);
    let serial_time = started.elapsed();

    let started = Instant::now();
    let many = threaded_sum(&values, 4);
    let threaded_time = started.elapsed();

    assert_eq!(one, many);
    println!("total {one}");
    println!("serial   {:?}", serial_time);
    println!("threaded {:?}", threaded_time);

    let ratio = serial_time.as_secs_f64() / threaded_time.as_secs_f64();
    println!("speedup {:.2}x", ratio);
}

How it works

  1. The data is chunked and each chunk goes to its own thread.
  2. Scoped threads borrow the slice instead of cloning it.
  3. The timing shows what the extra threads bought.

Keywords and builtins used here

The run, in numbers

Lines
41
Characters to type
922
Tokens
283
Three-star pace
110 tpm

At the three-star pace of 110 tokens a minute, this run takes about 154 seconds.

Type this snippet

Step 1 of 1 in Encore, step 15 of 15 in Concurrency & async.

← Previous