ここを参考に
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
- 作者: Jim Blandy,Jason Orendorff
- 出版社/メーカー: O'Reilly Media
- 発売日: 2017/11/21
- メディア: Kindle版
- この商品を含むブログを見る