From 6bd22494e9a2d3ce03ab0a6ec71bd9fc87f2a706 Mon Sep 17 00:00:00 2001 From: Guillaume Pinot Date: Thu, 28 Nov 2013 20:46:59 +0100 Subject: [PATCH] shootout-spectralnorm resurection with parallelization --- src/test/bench/shootout-spectralnorm.rs | 97 +++++++++++++++++-------- 1 file changed, 66 insertions(+), 31 deletions(-) diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs index 6a9837fb832ca..87cd01f9aad2e 100644 --- a/src/test/bench/shootout-spectralnorm.rs +++ b/src/test/bench/shootout-spectralnorm.rs @@ -8,59 +8,94 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test reading from os::args()[1] - bogus! +extern mod extra; use std::from_str::FromStr; +use std::iter::count; +use std::num::min; use std::os; -use std::vec; +use std::vec::from_elem; +use extra::arc::Arc; +use extra::arc::RWArc; -#[inline] -fn A(i: i32, j: i32) -> i32 { - (i+j) * (i+j+1) / 2 + i + 1 +fn A(i: uint, j: uint) -> f64 { + ((i + j) * (i + j + 1) / 2 + i + 1) as f64 } fn dot(v: &[f64], u: &[f64]) -> f64 { let mut sum = 0.0; - for (i, &v_i) in v.iter().enumerate() { - sum += v_i * u[i]; + for (&v_i, &u_i) in v.iter().zip(u.iter()) { + sum += v_i * u_i; } sum } -fn mult_Av(v: &mut [f64], out: &mut [f64]) { - for (i, out_i) in out.mut_iter().enumerate() { - let mut sum = 0.0; - for (j, &v_j) in v.mut_iter().enumerate() { - sum += v_j / (A(i as i32, j as i32) as f64); +fn mult(v: RWArc<~[f64]>, out: RWArc<~[f64]>, f: fn(&~[f64], uint) -> f64) { + let wait = Arc::new(()); + let len = out.read(|out| out.len()); + let chunk = len / 100 + 1; + for chk in count(0, chunk) { + if chk >= len {break;} + let w = wait.clone(); + let v = v.clone(); + let out = out.clone(); + do spawn { + for i in range(chk, min(len, chk + chunk)) { + let val = v.read(|v| f(v, i)); + out.write(|out| out[i] = val); + } + let _ = w; } - *out_i = sum; } + let _ = wait.unwrap(); } -fn mult_Atv(v: &mut [f64], out: &mut [f64]) { - for (i, out_i) in out.mut_iter().enumerate() { - let mut sum = 0.0; - for (j, &v_j) in v.mut_iter().enumerate() { - sum += v_j / (A(j as i32, i as i32) as f64); - } - *out_i = sum; +fn mult_Av_impl(v: &~[f64], i: uint) -> f64 { + let mut sum = 0.; + for (j, &v_j) in v.iter().enumerate() { + sum += v_j / A(i, j); } + sum +} + +fn mult_Av(v: RWArc<~[f64]>, out: RWArc<~[f64]>) { + mult(v, out, mult_Av_impl); } -fn mult_AtAv(v: &mut [f64], out: &mut [f64], tmp: &mut [f64]) { - mult_Av(v, tmp); +fn mult_Atv_impl(v: &~[f64], i: uint) -> f64 { + let mut sum = 0.; + for (j, &v_j) in v.iter().enumerate() { + sum += v_j / A(j, i); + } + sum +} + +fn mult_Atv(v: RWArc<~[f64]>, out: RWArc<~[f64]>) { + mult(v, out, mult_Atv_impl); +} + +fn mult_AtAv(v: RWArc<~[f64]>, out: RWArc<~[f64]>, tmp: RWArc<~[f64]>) { + mult_Av(v, tmp.clone()); mult_Atv(tmp, out); } fn main() { - let n: uint = FromStr::from_str(os::args()[1]).unwrap(); - let mut u = vec::from_elem(n, 1f64); - let mut v = u.clone(); - let mut tmp = u.clone(); - for _ in range(0, 8u) { - mult_AtAv(u, v, tmp); - mult_AtAv(v, u, tmp); + let args = os::args(); + let n = if os::getenv("RUST_BENCH").is_some() { + 5500 + } else if args.len() < 2 { + 2000 + } else { + FromStr::from_str(args[1]).unwrap() + }; + let u = RWArc::new(from_elem(n, 1.)); + let v = RWArc::new(from_elem(n, 1.)); + let tmp = RWArc::new(from_elem(n, 1.)); + for _ in range(0, 10) { + mult_AtAv(u.clone(), v.clone(), tmp.clone()); + mult_AtAv(v.clone(), u.clone(), tmp.clone()); } - - println!("{:.9f}", (dot(u,v) / dot(v,v)).sqrt() as float); + let u = u.unwrap(); + let v = v.unwrap(); + println!("{:.9f}", (dot(u,v) / dot(v,v)).sqrt()); }