Skip to content

Commit 66b7c11

Browse files
committed
shootout-mandelbrot rewrite
- removed warning - improved performances - parallelization
1 parent e0d261e commit 66b7c11

File tree

1 file changed

+52
-55
lines changed

1 file changed

+52
-55
lines changed

src/test/bench/shootout-mandelbrot.rs

Lines changed: 52 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -8,72 +8,69 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use std::io;
11+
extern crate sync;
1212

13-
struct DummyWriter;
14-
impl Writer for DummyWriter {
15-
fn write(&mut self, _: &[u8]) -> io::IoResult<()> { Ok(()) }
16-
}
13+
use std::io;
14+
use sync::Future;
1715

1816
static ITER: int = 50;
1917
static LIMIT: f64 = 2.0;
2018

21-
fn main() {
22-
let args = std::os::args();
23-
let (w, mut out) = if args.len() < 2 {
24-
println!("Test mode: do not dump the image because it's not utf8, \
25-
which interferes with the test runner.");
26-
(1000, ~DummyWriter as ~Writer)
27-
} else {
28-
(from_str(args[1]).unwrap(),
29-
~std::io::stdout() as ~Writer)
30-
};
31-
let h = w;
32-
let mut byte_acc = 0u8;
33-
let mut bit_num = 0;
34-
35-
writeln!(out, "P4\n{} {}", w, h);
36-
37-
for y in range(0, h) {
38-
let y = y as f64;
39-
for x in range(0, w) {
40-
let mut z_r = 0f64;
41-
let mut z_i = 0f64;
42-
let mut t_r = 0f64;
43-
let mut t_i = 0f64;
44-
let c_r = 2.0 * (x as f64) / (w as f64) - 1.5;
45-
let c_i = 2.0 * (y as f64) / (h as f64) - 1.0;
46-
19+
fn write_line(init_i: f64, vec_init_r: &[f64], res: &mut Vec<u8>) {
20+
for chunk_init_r in vec_init_r.chunks(8) {
21+
let mut cur_byte = 0xff;
22+
let mut cur_bitmask = 0x80;
23+
for &init_r in chunk_init_r.iter() {
24+
let mut cur_r = init_r;
25+
let mut cur_i = init_i;
4726
for _ in range(0, ITER) {
48-
if t_r + t_i > LIMIT * LIMIT {
27+
let r = cur_r;
28+
let i = cur_i;
29+
cur_r = r * r - i * i + init_r;
30+
cur_i = 2.0 * r * i + init_i;
31+
32+
if r * r + i * i > LIMIT * LIMIT {
33+
cur_byte &= !cur_bitmask;
4934
break;
5035
}
51-
52-
z_i = 2.0 * z_r * z_i + c_i;
53-
z_r = t_r - t_i + c_r;
54-
t_r = z_r * z_r;
55-
t_i = z_i * z_i;
56-
}
57-
58-
byte_acc <<= 1;
59-
if t_r + t_i <= LIMIT * LIMIT {
60-
byte_acc |= 1;
6136
}
37+
cur_bitmask >>= 1;
38+
}
39+
res.push(cur_byte);
40+
}
41+
}
6242

63-
bit_num += 1;
43+
fn mandelbrot<W: io::Writer>(w: uint, mut out: W) -> io::IoResult<()> {
44+
// Ensure w and h are multiples of 8.
45+
let w = (w + 7) / 8 * 8;
46+
let h = w;
47+
let chunk_size = h / 8;
6448

65-
if bit_num == 8 {
66-
out.write_u8(byte_acc);
67-
byte_acc = 0;
68-
bit_num = 0;
69-
} else if x == w - 1 {
70-
byte_acc <<= 8 - w % 8;
71-
out.write_u8(byte_acc);
72-
byte_acc = 0;
73-
bit_num = 0;
74-
}
49+
let data: Vec<Future<Vec<u8>>> = range(0u, 8).map(|i| Future::spawn(proc () {
50+
let vec_init_r = Vec::from_fn(w, |x| 2.0 * (x as f64) / (w as f64) - 1.5);
51+
let mut res: Vec<u8> = Vec::with_capacity((chunk_size * w) / 8);
52+
for y in range(i * chunk_size, (i + 1) * chunk_size) {
53+
let init_i = 2.0 * (y as f64) / (h as f64) - 1.0;
54+
write_line(init_i, vec_init_r.as_slice(), &mut res);
7555
}
56+
res
57+
})).collect();
58+
59+
try!(writeln!(&mut out as &mut Writer, "P4\n{} {}", w, h));
60+
for res in data.move_iter() {
61+
try!(out.write(res.unwrap().as_slice()));
7662
}
63+
out.flush()
64+
}
7765

78-
out.flush();
66+
fn main() {
67+
let args = std::os::args();
68+
let res = if args.len() < 2 {
69+
println!("Test mode: do not dump the image because it's not utf8, \
70+
which interferes with the test runner.");
71+
mandelbrot(1000, std::io::util::NullWriter)
72+
} else {
73+
mandelbrot(from_str(args[1]).unwrap(), std::io::stdout())
74+
};
75+
res.unwrap();
7976
}

0 commit comments

Comments
 (0)