diff options
| author | Ben Blum <bblum@andrew.cmu.edu> | 2012-08-21 19:37:43 -0400 |
|---|---|---|
| committer | Ben Blum <bblum@andrew.cmu.edu> | 2012-08-21 19:40:47 -0400 |
| commit | 7fe1005fd124fe79f4a4ea17d0056e55ff7bd3ae (patch) | |
| tree | 4da8bffa2f983416b0f2937561745917f97ac810 /src/test | |
| parent | 236f8330072aec35f875f029dc215769e5fc6b91 (diff) | |
| download | rust-7fe1005fd124fe79f4a4ea17d0056e55ff7bd3ae.tar.gz rust-7fe1005fd124fe79f4a4ea17d0056e55ff7bd3ae.zip | |
Add msgsend-ring-{rw,mutex}-arcs bench tests
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/bench/msgsend-ring-mutex-arcs.rs | 114 | ||||
| -rw-r--r-- | src/test/bench/msgsend-ring-rw-arcs.rs | 115 |
2 files changed, 229 insertions, 0 deletions
diff --git a/src/test/bench/msgsend-ring-mutex-arcs.rs b/src/test/bench/msgsend-ring-mutex-arcs.rs new file mode 100644 index 00000000000..172351e506f --- /dev/null +++ b/src/test/bench/msgsend-ring-mutex-arcs.rs @@ -0,0 +1,114 @@ +// This test creates a bunch of tasks that simultaneously send to each +// other in a ring. The messages should all be basically +// independent. +// This is like msgsend-ring-pipes but adapted to use ARCs. + +// This also serves as a pipes test, because ARCs are implemented with pipes. + +// xfail-pretty + +import future::future; + +use std; +import std::time; +import std::arc; + +// A poor man's pipe. +type pipe = arc::mutex_arc<~[uint]>; + +fn send(p: &pipe, msg: uint) { + do p.access_cond |state, cond| { + vec::push(*state, msg); + cond.signal(); + } +} +fn recv(p: &pipe) -> uint { + do p.access_cond |state, cond| { + while vec::is_empty(*state) { + cond.wait(); + } + vec::pop(*state) + } +} + +fn init() -> (pipe,pipe) { + let m = arc::mutex_arc(~[]); + ((&m).clone(), m) +} + + +fn thread_ring(i: uint, + count: uint, + +num_chan: pipe, + +num_port: pipe) { + let mut num_chan <- some(num_chan); + let mut num_port <- some(num_port); + // Send/Receive lots of messages. + for uint::range(0u, count) |j| { + //error!{"task %?, iter %?", i, j}; + let mut num_chan2 = option::swap_unwrap(&mut num_chan); + let mut num_port2 = option::swap_unwrap(&mut num_port); + send(&num_chan2, i * j); + num_chan = some(num_chan2); + let _n = recv(&num_port2); + //log(error, _n); + num_port = some(num_port2); + }; +} + +fn main(args: ~[~str]) { + let args = if os::getenv(~"RUST_BENCH").is_some() { + ~[~"", ~"100", ~"10000"] + } else if args.len() <= 1u { + ~[~"", ~"10", ~"100"] + } else { + copy args + }; + + let num_tasks = option::get(uint::from_str(args[1])); + let msg_per_task = option::get(uint::from_str(args[2])); + + let (num_chan, num_port) = init(); + let mut num_chan = some(num_chan); + + let start = time::precise_time_s(); + + // create the ring + let mut futures = ~[]; + + for uint::range(1u, num_tasks) |i| { + //error!{"spawning %?", i}; + let (new_chan, num_port) = init(); + let num_chan2 = ~mut none; + *num_chan2 <-> num_chan; + let num_port = ~mut some(num_port); + futures += ~[future::spawn(|move num_chan2, move num_port| { + let mut num_chan = none; + num_chan <-> *num_chan2; + let mut num_port1 = none; + num_port1 <-> *num_port; + thread_ring(i, msg_per_task, + option::unwrap(num_chan), + option::unwrap(num_port1)) + })]; + num_chan = some(new_chan); + }; + + // do our iteration + thread_ring(0u, msg_per_task, option::unwrap(num_chan), num_port); + + // synchronize + for futures.each |f| { future::get(&f) }; + + let stop = time::precise_time_s(); + + // all done, report stats. + let num_msgs = num_tasks * msg_per_task; + let elapsed = (stop - start); + let rate = (num_msgs as float) / elapsed; + + io::println(fmt!{"Sent %? messages in %? seconds", + num_msgs, elapsed}); + io::println(fmt!{" %? messages / second", rate}); + io::println(fmt!{" %? μs / message", 1000000. / rate}); +} diff --git a/src/test/bench/msgsend-ring-rw-arcs.rs b/src/test/bench/msgsend-ring-rw-arcs.rs new file mode 100644 index 00000000000..6dcaabdb56e --- /dev/null +++ b/src/test/bench/msgsend-ring-rw-arcs.rs @@ -0,0 +1,115 @@ +// This test creates a bunch of tasks that simultaneously send to each +// other in a ring. The messages should all be basically +// independent. +// This is like msgsend-ring-pipes but adapted to use ARCs. + +// This also serves as a pipes test, because ARCs are implemented with pipes. + +// xfail-pretty + +import future::future; + +use std; +import std::time; +import std::arc; + +// A poor man's pipe. +type pipe = arc::rw_arc<~[uint]>; + +fn send(p: &pipe, msg: uint) { + do p.write_cond |state, cond| { + vec::push(*state, msg); + cond.signal(); + } +} +fn recv(p: &pipe) -> uint { + do p.write_cond |state, cond| { + while vec::is_empty(*state) { + error!("have to wait"); + cond.wait(); + } + vec::pop(*state) + } +} + +fn init() -> (pipe,pipe) { + let x = arc::rw_arc(~[]); + ((&x).clone(), x) +} + + +fn thread_ring(i: uint, + count: uint, + +num_chan: pipe, + +num_port: pipe) { + let mut num_chan <- some(num_chan); + let mut num_port <- some(num_port); + // Send/Receive lots of messages. + for uint::range(0u, count) |j| { + //error!{"task %?, iter %?", i, j}; + let mut num_chan2 = option::swap_unwrap(&mut num_chan); + let mut num_port2 = option::swap_unwrap(&mut num_port); + send(&num_chan2, i * j); + num_chan = some(num_chan2); + let _n = recv(&num_port2); + //log(error, _n); + num_port = some(num_port2); + }; +} + +fn main(args: ~[~str]) { + let args = if os::getenv(~"RUST_BENCH").is_some() { + ~[~"", ~"100", ~"10000"] + } else if args.len() <= 1u { + ~[~"", ~"10", ~"100"] + } else { + copy args + }; + + let num_tasks = option::get(uint::from_str(args[1])); + let msg_per_task = option::get(uint::from_str(args[2])); + + let (num_chan, num_port) = init(); + let mut num_chan = some(num_chan); + + let start = time::precise_time_s(); + + // create the ring + let mut futures = ~[]; + + for uint::range(1u, num_tasks) |i| { + //error!{"spawning %?", i}; + let (new_chan, num_port) = init(); + let num_chan2 = ~mut none; + *num_chan2 <-> num_chan; + let num_port = ~mut some(num_port); + futures += ~[future::spawn(|move num_chan2, move num_port| { + let mut num_chan = none; + num_chan <-> *num_chan2; + let mut num_port1 = none; + num_port1 <-> *num_port; + thread_ring(i, msg_per_task, + option::unwrap(num_chan), + option::unwrap(num_port1)) + })]; + num_chan = some(new_chan); + }; + + // do our iteration + thread_ring(0u, msg_per_task, option::unwrap(num_chan), num_port); + + // synchronize + for futures.each |f| { future::get(&f) }; + + let stop = time::precise_time_s(); + + // all done, report stats. + let num_msgs = num_tasks * msg_per_task; + let elapsed = (stop - start); + let rate = (num_msgs as float) / elapsed; + + io::println(fmt!{"Sent %? messages in %? seconds", + num_msgs, elapsed}); + io::println(fmt!{" %? messages / second", rate}); + io::println(fmt!{" %? μs / message", 1000000. / rate}); +} |
