e-tipsmemo

ごった煮

Rustでマルチスレッド 試用

rustbyexample.com

ここを参考に
e-tipsmemo.hatenablog.com
をマルチスレッド化してみる。
ついでに積分計算は台形で行うように変更した。

extern crate test;

use std::thread;

#[derive(Debug, Copy, Clone)]
struct Fx {
    a: f64,
    b: f64,
    step: u64,
    f: fn(f64) -> f64,
}

impl Fx {
    fn new(a: f64, b: f64, step: u64, f: fn(f64) -> f64) -> Fx {
        Fx {
            a: a,
            b: b,
            step: step,
            f: f,
        }
    }
}

fn integral(p: &Fx) -> f64 {
    let dx = (p.b - p.a) / (p.step as f64);

    let mut sum = 0.0;

    for n in 0..p.step {
        let x = p.a + dx * (n as f64);
        let bar = ((p.f)(x) + (p.f)(x + dx)) * dx / 2.0;
        sum = sum + bar;
    }
    sum
}

#[cfg(test)]
mod tests {
    use super::*;

    const a: f64 = 0.0;
    const b: f64 = 1.0;
    const thread: u64 = 4;
    const onestep: u64 = 10000000;

    fn f(x: f64) -> f64 {
        x * x + 1.0
    }

    #[test]
    fn int_test() {
        let prim = Fx::new(a, b, thread * onestep, f);
        println!("single:{:?}", integral(&prim));
    }

    #[test]
    fn int_thread_test {
        let mut pvec = vec![];
        let x = (b - a) / (thread as f64);
        let ti = thread as usize;

        for t in 0..thread {
            let at = a + x * (t as f64);
            let bt = a + x * (t as f64) + x;
            let prim = Fx::new(at, bt, onestep, f);
            pvec.push(prim);
        }

        let mut children = vec![];
        let mut data = vec![];

        for i in 0..ti {
            let p = pvec[i];
            children.push(thread::spawn(move || integral(&p)));
        }

        for child in children {
            data.push(child.join().unwrap());
        }

        let res = data.iter().fold(0.0, |s, &t| s + t);
        println!("{:?}", data);
        println!("multi:{:?}", res);
    }
}

fn main() {
    let handle = thread::spawn(|| {
        println!("Hello, thread World!");
    });

    let _ = handle.join();
}

雰囲気で書いたがうまく書かないとマルチスレッドで速くなるとは限らない?

実行

$ cargo test
.....
    Finished dev [unoptimized + debuginfo] target(s) in 1.4 secs
     Running target/debug/deps/multi-eddd85052ba1c1ac

running 2 tests
[0.25520833333333814, 0.28645833333335946, 0.3489583333333194, 0.44270833333336124]
multi:1.3333333333333783
.single:1.3333333333332258
.
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured

値が少しだけ大きい。どこか足しすぎてるか?

Programming Rust: Fast, Safe Systems Development

Programming Rust: Fast, Safe Systems Development