|
|
|
@ -134,8 +134,19 @@ fn write_bitmap(filename: &str, pixels: &[u8], bounds: (usize, usize))
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use std::time::{Instant, Duration};
|
|
|
|
|
|
|
|
|
|
fn measure_elapsed_time<F: FnOnce()>(f: F) -> Duration {
|
|
|
|
|
let t0 = Instant::now();
|
|
|
|
|
f();
|
|
|
|
|
Instant::now() - t0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern crate crossbeam;
|
|
|
|
|
|
|
|
|
|
use std::sync::Mutex;
|
|
|
|
|
use std::io::Write;
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
@ -161,23 +172,46 @@ fn main() {
|
|
|
|
|
|
|
|
|
|
let mut pixels = vec![0; bounds.0 * bounds.1];
|
|
|
|
|
|
|
|
|
|
let threads = 8;
|
|
|
|
|
let shard_rows = bounds.1 / threads + 1;
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
let shards : Vec<_> = pixels.chunks_mut(shard_rows * bounds.0).collect();
|
|
|
|
|
crossbeam::scope(|scope| {
|
|
|
|
|
for (i, shard) in shards.into_iter().enumerate() {
|
|
|
|
|
let top = shard_rows * i;
|
|
|
|
|
let height = shard.len() / bounds.0;
|
|
|
|
|
let shard_bounds = (bounds.0, height);
|
|
|
|
|
scope.spawn(move || {
|
|
|
|
|
render(shard, shard_bounds,
|
|
|
|
|
pixel_to_point(bounds, (0, top), upper_left, lower_right),
|
|
|
|
|
pixel_to_point(bounds, (bounds.0, top + height), upper_left, lower_right));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
for threads in [1, 2, 3, 4, 5, 6, 7, 8,
|
|
|
|
|
9, 10, 11, 12, 13, 14, 15, 16,
|
|
|
|
|
20, 30, 40, 50, 60, 70, 80, 90,
|
|
|
|
|
//100, 200, 300, 400, 500, 600, 700, 800, 900, 1000
|
|
|
|
|
].iter() {
|
|
|
|
|
let band_rows = bounds.1 / 400;
|
|
|
|
|
|
|
|
|
|
let dt = measure_elapsed_time(|| {
|
|
|
|
|
let bands = Mutex::new(pixels.chunks_mut(band_rows * bounds.0).enumerate());
|
|
|
|
|
crossbeam::scope(|scope| {
|
|
|
|
|
for i in 0..*threads {
|
|
|
|
|
scope.spawn(|| {
|
|
|
|
|
let mut count = 0;
|
|
|
|
|
loop {
|
|
|
|
|
match {
|
|
|
|
|
let mut guard = bands.lock().unwrap();
|
|
|
|
|
guard.next()
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
None => { return; }
|
|
|
|
|
Some((i, band)) => {
|
|
|
|
|
count += 1;
|
|
|
|
|
let top = band_rows * i;
|
|
|
|
|
let height = band.len() / bounds.0;
|
|
|
|
|
let band_bounds = (bounds.0, height);
|
|
|
|
|
let band_upper_left = pixel_to_point(bounds, (0, top),
|
|
|
|
|
upper_left, lower_right);
|
|
|
|
|
let band_lower_right = pixel_to_point(bounds, (bounds.0, top + height),
|
|
|
|
|
upper_left, lower_right);
|
|
|
|
|
render(band, band_bounds, band_upper_left, band_lower_right);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
println!("{:4} {:.3}",
|
|
|
|
|
threads,
|
|
|
|
|
dt.as_secs() as f64 + dt.subsec_nanos() as f64 * 1e-9);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
write_bitmap(&args[1], &pixels[..], bounds).expect("error writing PNG file");
|
|
|
|
|