diff --git a/chorus_lib/Cargo.toml b/chorus_lib/Cargo.toml index 1bdc8dc..ad36aaf 100644 --- a/chorus_lib/Cargo.toml +++ b/chorus_lib/Cargo.toml @@ -28,5 +28,9 @@ rand = "0.8.5" termcolor = "1.2.0" [[bench]] -name = "chorus_benchmark" +name = "locally_benchmark" +harness = false + +[[bench]] +name = "comm_benchmark" harness = false diff --git a/chorus_lib/benches/chorus_benchmark.rs b/chorus_lib/benches/chorus_benchmark.rs deleted file mode 100644 index d3b8390..0000000 --- a/chorus_lib/benches/chorus_benchmark.rs +++ /dev/null @@ -1,133 +0,0 @@ -extern crate chorus_lib; - -use std::thread::spawn; - -use chorus_lib::{ - core::{ChoreoOp, Choreography, ChoreographyLocation, LocationSet, Projector, Transport}, - transport::local::{LocalTransport, LocalTransportChannelBuilder}, -}; -use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; - -#[derive(ChoreographyLocation)] -struct Alice; - -#[derive(ChoreographyLocation)] -struct Bob; - -struct AddToNChoreography { - n: u64, -} - -impl Choreography for AddToNChoreography { - type L = LocationSet!(Alice, Bob); - - fn run(self, op: &impl ChoreoOp) -> () { - let mut i = 0; - loop { - let tmp = op.locally(Alice, |_| i + 1); - i = op.broadcast(Alice, tmp); - if i >= self.n { - break; - } - let tmp = op.locally(Bob, |_| i + 1); - i = op.broadcast(Bob, tmp); - if i >= self.n { - break; - } - } - } -} - -fn add_to_n_choreography(n: u64) { - let c1 = AddToNChoreography { n }; - let c2 = AddToNChoreography { n }; - let channel = LocalTransportChannelBuilder::new() - .with(Alice) - .with(Bob) - .build(); - let mut handles = Vec::new(); - { - let channel = channel.clone(); - handles.push(spawn(move || { - let transport = LocalTransport::new(Alice, channel); - let projector = Projector::new(Alice, transport); - projector.epp_and_run(c1); - })); - } - { - let channel = channel.clone(); - handles.push(spawn(move || { - let transport = LocalTransport::new(Bob, channel); - let projector = Projector::new(Bob, transport); - projector.epp_and_run(c2); - })); - } - for handle in handles { - handle.join().unwrap(); - } -} - -fn add_to_n(n: u64) { - let n = n; - let mut handles = Vec::new(); - let channel = LocalTransportChannelBuilder::new() - .with(Alice) - .with(Bob) - .build(); - { - let channel = channel.clone(); - handles.push(spawn(move || { - let n = n; - let transport = LocalTransport::new(Alice, channel); - let mut i: u64 = 0; - loop { - i += 1; - transport.send("Alice", "Bob", &i); - if i >= n { - break; - } - i = transport.receive("Bob", "Alice"); - if i >= n { - break; - } - } - })); - } - { - let channel = channel.clone(); - handles.push(spawn(move || { - let n = n; - let transport = LocalTransport::new(Bob, channel); - loop { - let mut i = transport.receive::("Alice", "Bob"); - if i >= n { - break; - } - i += 1; - transport.send("Bob", "Alice", &i); - if i >= n { - break; - } - } - })); - } - for handle in handles { - handle.join().unwrap(); - } -} - -fn bench_add_to_n_local(c: &mut Criterion) { - let mut group = c.benchmark_group("Add to N (Local Transport)"); - for i in [1000].iter() { - group.bench_with_input(BenchmarkId::new("Choreographic", i), i, |b, i| { - b.iter(|| add_to_n_choreography(*i)) - }); - group.bench_with_input(BenchmarkId::new("Handwritten", i), i, |b, i| { - b.iter(|| add_to_n(*i)) - }); - } - group.finish(); -} - -criterion_group!(benches, bench_add_to_n_local); -criterion_main!(benches); diff --git a/chorus_lib/benches/comm_benchmark.rs b/chorus_lib/benches/comm_benchmark.rs new file mode 100644 index 0000000..74b8045 --- /dev/null +++ b/chorus_lib/benches/comm_benchmark.rs @@ -0,0 +1,115 @@ +use chorus_lib::core::{ + ChoreoOp, Choreography, ChoreographyLocation, LocationSet, Projector, Transport, +}; +use chorus_lib::transport::local::{LocalTransport, LocalTransportChannelBuilder}; +use criterion::{ + black_box, criterion_group, criterion_main, AxisScale, BenchmarkId, Criterion, + PlotConfiguration, +}; +use std::thread::spawn; + +#[derive(ChoreographyLocation)] +struct Alice; + +#[derive(ChoreographyLocation)] +struct Bob; + +struct CommChoreography { + n: u64, +} + +impl Choreography for CommChoreography { + type L = LocationSet!(Alice, Bob); + + fn run(self, op: &impl ChoreoOp) { + for _ in 0..self.n { + op.comm(Bob, Alice, &op.locally::(Bob, |_| 1.0)); + } + } +} + +fn comm_choreography(n: u64) { + let channel = LocalTransportChannelBuilder::new() + .with(Alice) + .with(Bob) + .build(); + let mut handles = Vec::new(); + { + let channel = channel.clone(); + handles.push(spawn(move || { + let transport = LocalTransport::new(Alice, channel); + let projector = Projector::new(Alice, transport); + let c = CommChoreography { n }; + projector.epp_and_run(c); + })); + } + { + let channel = channel.clone(); + handles.push(spawn(move || { + let transport = LocalTransport::new(Bob, channel); + let projector = Projector::new(Bob, transport); + let c = CommChoreography { n }; + projector.epp_and_run(c); + })); + } + for handle in handles { + handle.join().unwrap(); + } +} + +fn comm_handwritten_alice(n: u64, transport: &LocalTransport) { + for _ in 0..n { + transport.receive::(Bob::name(), Alice::name()); + } +} + +fn comm_handwritten_bob(n: u64, transport: &LocalTransport) { + for _ in 0..n { + transport.send::(Bob::name(), Alice::name(), &1.0); + } +} + +fn comm_handwritten(n: u64) { + let channel = LocalTransportChannelBuilder::new() + .with(Alice) + .with(Bob) + .build(); + let mut handles = Vec::new(); + { + let channel = channel.clone(); + handles.push(spawn(move || { + let transport = LocalTransport::new(Alice, channel); + comm_handwritten_alice(n, &transport); + })); + } + { + let channel = channel.clone(); + handles.push(spawn(move || { + let transport = LocalTransport::new(Bob, channel); + comm_handwritten_bob(n, &transport); + })); + } + for handle in handles { + handle.join().unwrap(); + } +} + +fn bench_comm(c: &mut Criterion) { + let mut group = c.benchmark_group("Comm"); + let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic); + group.plot_config(plot_config); + for i in [1, 10, 100, 1000, 10000].iter() { + group.bench_with_input(BenchmarkId::new("Handwritten", i), i, |b, i| { + b.iter(|| comm_handwritten(black_box(*i))) + }); + } + for i in [1, 10, 100, 1000, 10000].iter() { + group.bench_with_input(BenchmarkId::new("Choreographic", i), i, |b, i| { + b.iter(|| comm_choreography(black_box(*i))) + }); + } + group.finish(); +} + +criterion_group!(benches, bench_comm); +criterion_main!(benches); diff --git a/chorus_lib/benches/locally_benchmark.rs b/chorus_lib/benches/locally_benchmark.rs new file mode 100644 index 0000000..a00592b --- /dev/null +++ b/chorus_lib/benches/locally_benchmark.rs @@ -0,0 +1,65 @@ +use chorus_lib::core::{ChoreoOp, Choreography, ChoreographyLocation, Located, LocationSet}; +use criterion::{ + black_box, criterion_group, criterion_main, AxisScale, BenchmarkId, Criterion, + PlotConfiguration, +}; + +#[derive(ChoreographyLocation)] +struct Alice; + +struct AddToNLocallyChoreography { + n: f64, +} +impl Choreography> for AddToNLocallyChoreography { + type L = LocationSet!(Alice); + + fn run(self, op: &impl ChoreoOp) -> Located { + let mut i = op.locally(Alice, |_| 0.0); + for _ in 0..self.n.ceil() as u64 { + i = op.locally(Alice, |un| *un.unwrap(&i) + 1.0); + } + return i; + } +} + +fn add_to_n_locally_choreographic(n: f64) { + let c = AddToNLocallyChoreography { n }; + let channel = chorus_lib::transport::local::LocalTransportChannelBuilder::new() + .with(Alice) + .build(); + let transport = chorus_lib::transport::local::LocalTransport::new(Alice, channel); + let projector = chorus_lib::core::Projector::new(Alice, transport); + let result = projector.epp_and_run(c); + assert_eq!(projector.unwrap(result), n); +} + +fn add_to_n_locally_handwritten(n: f64) { + let mut a: f64 = 0.0; + for _ in 0..n.ceil() as u64 { + a += 1.0; + } + assert_eq!(a, n); +} + +fn bench_add_to_n_locally(c: &mut Criterion) { + let mut group = c.benchmark_group("Locally"); + let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic); + // group.plot_config(plot_config); + // let range = [1, 10, 100, 1000, 10000]; + let range = [2000, 4000, 6000, 8000, 10000]; + for i in range.iter() { + group.bench_with_input(BenchmarkId::new("Handwritten", i), i, |b, i| { + b.iter(|| add_to_n_locally_handwritten(black_box(*i as f64))) + }); + } + for i in range.iter() { + group.bench_with_input(BenchmarkId::new("Choreographic", i), i, |b, i| { + b.iter(|| add_to_n_locally_choreographic(black_box(*i as f64))) + }); + } + + group.finish(); +} + +criterion_group!(benches, bench_add_to_n_locally); +criterion_main!(benches);