performance measurements

Each table row shows performance measurements for this Rust program with a particular command-line input value N.

 N  CPU secs Elapsed secs Memory KB Code B ≈ CPU Load

Read the ↓ make, command line, and program output logs to see how this program was run.

Read mandelbrot benchmark to see what this program should do.

 notes

rustc 1.1.0 (35ceea399 2015-06-19)

 mandelbrot Rust program source code

// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers
// contributed by TeXitoi

#![feature(core, os, old_io, env)]

use std::old_io;
use std::simd::f64x2;
use std::sync::Arc;
use std::thread::scoped;

const ITER: i32 = 50;
const LIMIT: f64 = 2.0;
const WORKERS: usize = 16;

#[inline(always)]
fn mandelbrot<W: old_io::Writer>(w: usize, mut out: W) -> old_io::IoResult<()> {
    assert!(WORKERS % 2 == 0);

    // Ensure w and h are multiples of 8.
    let w = (w + 7) / 8 * 8;
    let h = w;

    let chunk_size = h / WORKERS;

    // Account for remainders in workload division, e.g. 1000 / 16 = 62.5
    let last_chunk_size = if h % WORKERS != 0 {
        chunk_size + h % WORKERS
    } else {
        chunk_size
    };

    // precalc values
    let inverse_w_doubled = 2.0 / w as f64;
    let inverse_h_doubled = 2.0 / h as f64;
    let v_inverses = f64x2(inverse_w_doubled, inverse_h_doubled);
    let v_consts = f64x2(1.5, 1.0);

    // A lot of this code assumes this (so do other lang benchmarks)
    assert!(w == h);
    let mut precalc_r = Vec::with_capacity(w);
    let mut precalc_i = Vec::with_capacity(h);

    let precalc_futures = range(0, WORKERS).map(|i| {
        scoped(move|| {
            let mut rs = Vec::with_capacity(w / WORKERS);
            let mut is = Vec::with_capacity(w / WORKERS);

            let start = i * chunk_size;
            let end = if i == (WORKERS - 1) {
                start + last_chunk_size
            } else {
                (i + 1) * chunk_size
            };

            // This assumes w == h
            for x in range(start, end) {
                let xf = x as f64;
                let xy = f64x2(xf, xf);

                let f64x2(r, i) = xy * v_inverses - v_consts;
                rs.push(r);
                is.push(i);
            }

            (rs, is)
        })
    }).collect::<Vec<_>>();

    for res in precalc_futures.into_iter() {
        let (rs, is) = res.join();
        precalc_r.extend(rs.into_iter());
        precalc_i.extend(is.into_iter());
    }

    assert_eq!(precalc_r.len(), w);
    assert_eq!(precalc_i.len(), h);

    let arc_init_r = Arc::new(precalc_r);
    let arc_init_i = Arc::new(precalc_i);

    let data = range(0, WORKERS).map(|i| {
        let vec_init_r = arc_init_r.clone();
        let vec_init_i = arc_init_i.clone();

        scoped(move|| {
            let mut res: Vec<u8> = Vec::with_capacity((chunk_size * w) / 8);
            let init_r_slice = vec_init_r.as_slice();

            let start = i * chunk_size;
            let end = if i == (WORKERS - 1) {
                start + last_chunk_size
            } else {
                (i + 1) * chunk_size
            };

            for &init_i in vec_init_i[start..end].iter() {
                write_line(init_i, init_r_slice, &mut res);
            }

            res
        })
    }).collect::<Vec<_>>();

    try!(writeln!(&mut out as &mut Writer, "P4\n{} {}", w, h));
    for res in data.into_iter() {
        try!(out.write_all(&res.join()));
    }
    out.flush()
}

fn write_line(init_i: f64, vec_init_r: &[f64], res: &mut Vec<u8>) {
    let v_init_i : f64x2 = f64x2(init_i, init_i);
    let v_2 : f64x2 = f64x2(2.0, 2.0);
    const LIMIT_SQUARED: f64 = LIMIT * LIMIT;

    for chunk_init_r in vec_init_r.chunks(8) {
        let mut cur_byte = 0xff;
        let mut i = 0;

        while i < 8 {
            let v_init_r = f64x2(chunk_init_r[i], chunk_init_r[i + 1]);
            let mut cur_r = v_init_r;
            let mut cur_i = v_init_i;
            let mut r_sq = v_init_r * v_init_r;
            let mut i_sq = v_init_i * v_init_i;

            let mut b = 0;
            for _ in range(0, ITER) {
                let r = cur_r;
                let i = cur_i;

                cur_i = v_2 * r * i + v_init_i;
                cur_r = r_sq - i_sq + v_init_r;

                let f64x2(bit1, bit2) = r_sq + i_sq;

                if bit1 > LIMIT_SQUARED {
                    b |= 2;
                    if b == 3 { break; }
                }

                if bit2 > LIMIT_SQUARED {
                    b |= 1;
                    if b == 3 { break; }
                }

                r_sq = cur_r * cur_r;
                i_sq = cur_i * cur_i;
            }

            cur_byte = (cur_byte << 2) + b;
            i += 2;
        }

        res.push(cur_byte^-1);
    }
}

fn main() {
    let n = std::env::args_os().nth(1)
        .and_then(|s| s.into_string().ok())
        .and_then(|n| n.parse().ok())
        .unwrap_or(200);
    mandelbrot(n, old_io::stdout()).unwrap();
}

 make, command-line, and program output logs

Mon, 18 May 2015 20:31:18 GMT

MAKE:
/usr/local/src/rust-1.0.0-i686-unknown-linux-gnu/rustc/bin/rustc -C opt-level=3 -C target-cpu=core2 -C lto  mandelbrot.rs -o mandelbrot.rust_run
mandelbrot.rs:9:5: 9:16 error: unresolved import `std::old_io`. There is no `old_io` in `std`
mandelbrot.rs:9 use std::old_io;
                    ^~~~~~~~~~~
error: aborting due to previous error
/home/dunham/benchmarksgame/nanobench/makefiles/u32q.programs.Makefile:616: recipe for target 'mandelbrot.rust_run' failed
make: [mandelbrot.rust_run] Error 101 (ignored)
rm mandelbrot.rs
0.11s to complete and log all make actions

COMMAND LINE:
./mandelbrot.rust_run 1000

MAKE ERROR 

Revised BSD license

  Home   Conclusions   License   Play