rust/src/test/bench/shootout-pfib.rs

124 lines
2.6 KiB
Rust
Raw Normal View History

// -*- rust -*-
/*
A parallel version of fibonacci numbers.
This version is meant mostly as a way of stressing and benchmarking
the task system. It supports a lot of command-line arguments to
control how it runs.
*/
use std;
import std::vec;
import std::uint;
import std::time;
import std::str;
import std::int::range;
import std::io;
2011-07-07 19:28:20 -05:00
import std::getopts;
import std::task;
import std::u64;
fn recv[T](&port[T] p) -> T {
let T x;
p |> x;
ret x;
}
fn fib(int n) -> int {
fn pfib(chan[int] c, int n) {
if (n == 0) {
c <| 0;
}
else if (n <= 2) {
c <| 1;
}
else {
2011-07-07 19:28:20 -05:00
auto p = port();
auto t1 = spawn pfib(chan(p), n - 1);
auto t2 = spawn pfib(chan(p), n - 2);
c <| recv(p) + recv(p);
}
}
2011-07-07 19:28:20 -05:00
auto p = port();
auto t = spawn pfib(chan(p), n);
ret recv(p);
}
2011-07-07 19:28:20 -05:00
type config = rec(bool stress);
fn parse_opts(vec[str] argv) -> config {
auto opts = [getopts::optflag("stress")];
auto opt_args = vec::slice(argv, 1u, vec::len(argv));
alt(getopts::getopts(opt_args, opts)) {
case(getopts::success(?m)) {
ret rec(stress = getopts::opt_present(m, "stress"))
}
case(getopts::failure(_)) {
fail;
}
}
}
fn stress_task(int id) {
auto i = 0;
while(true) {
auto n = 15;
assert(fib(n) == fib(n));
i += 1;
log_err #fmt("%d: Completed %d iterations", id, i);
}
}
fn stress(int num_tasks) {
auto tasks = [];
for each(int i in range(0, num_tasks)) {
tasks += [spawn stress_task(i)];
}
for each(int i in range(0, num_tasks)) {
task::join(tasks.(i));
}
2011-07-07 19:28:20 -05:00
}
fn main(vec[str] argv) {
if(vec::len(argv) == 1u) {
assert (fib(8) == 21);
log fib(8);
}
else {
// Interactive mode! Wooo!!!!
2011-07-07 19:28:20 -05:00
auto opts = parse_opts(argv);
2011-07-07 19:28:20 -05:00
if(opts.stress) {
stress(2);
}
else {
auto max = uint::parse_buf(str::bytes(argv.(1)), 10u) as int;
2011-07-07 19:28:20 -05:00
auto num_trials = 10;
2011-07-07 19:28:20 -05:00
auto out = io::stdout();
2011-07-07 19:28:20 -05:00
for each(int n in range(1, max + 1)) {
for each(int i in range(0, num_trials)) {
auto start = time::precise_time_ns();
auto fibn = fib(n);
auto stop = time::precise_time_ns();
auto elapsed = stop - start;
out.write_line(#fmt("%d\t%d\t%s", n, fibn,
u64::str(elapsed)));
2011-07-07 19:28:20 -05:00
}
}
}
}
}