Skip to content

Commit

Permalink
Merge pull request #362 from elfenpiff/iox2-360-benchmark-improvements
Browse files Browse the repository at this point in the history
[#360] benchmark improvements
  • Loading branch information
elfenpiff authored Aug 30, 2024
2 parents 50b6387 + 02fe98d commit 6089d60
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 67 deletions.
2 changes: 1 addition & 1 deletion benchmarks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ reception to promptly respond with a return signal notification. This process re
times, and the average latency is subsequently computed.

```sh
cargo run --bin benchmark-event --release -- -i 10000
cargo run --bin benchmark-event --release -- --bench-all
```

For more benchmark configuration details, see
Expand Down
82 changes: 59 additions & 23 deletions benchmarks/event/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,29 +43,35 @@ fn perform_benchmark<T: Service>(args: &Args) {
let barrier_handle = BarrierHandle::new();
let barrier = BarrierBuilder::new(3).create(&barrier_handle).unwrap();

let t1 = ThreadBuilder::new().affinity(0).priority(255).spawn(|| {
let notifier_a2b = service_a2b.notifier_builder().create().unwrap();
let listener_b2a = service_b2a.listener_builder().create().unwrap();

barrier.wait();
notifier_a2b.notify().expect("failed to notify");

for _ in 0..args.iterations {
while listener_b2a.blocking_wait_one().unwrap().is_none() {}
let t1 = ThreadBuilder::new()
.affinity(args.cpu_core_thread_1)
.priority(255)
.spawn(|| {
let notifier_a2b = service_a2b.notifier_builder().create().unwrap();
let listener_b2a = service_b2a.listener_builder().create().unwrap();

barrier.wait();
notifier_a2b.notify().expect("failed to notify");
}
});

let t2 = ThreadBuilder::new().affinity(1).priority(255).spawn(|| {
let notifier_b2a = service_b2a.notifier_builder().create().unwrap();
let listener_a2b = service_a2b.listener_builder().create().unwrap();

barrier.wait();
for _ in 0..args.iterations {
while listener_a2b.blocking_wait_one().unwrap().is_none() {}
notifier_b2a.notify().expect("failed to notify");
}
});
for _ in 0..args.iterations {
while listener_b2a.blocking_wait_one().unwrap().is_none() {}
notifier_a2b.notify().expect("failed to notify");
}
});

let t2 = ThreadBuilder::new()
.affinity(args.cpu_core_thread_2)
.priority(255)
.spawn(|| {
let notifier_b2a = service_b2a.notifier_builder().create().unwrap();
let listener_a2b = service_a2b.listener_builder().create().unwrap();

barrier.wait();
for _ in 0..args.iterations {
while listener_a2b.blocking_wait_one().unwrap().is_none() {}
notifier_b2a.notify().expect("failed to notify");
}
});

std::thread::sleep(std::time::Duration::from_millis(100));
let start = Time::now().expect("failed to acquire time");
Expand Down Expand Up @@ -94,12 +100,27 @@ struct Args {
/// Number of iterations the A --> B --> A communication is repeated
#[clap(short, long, default_value_t = ITERATIONS)]
iterations: usize,
/// Run benchmark for every service setup
#[clap(short, long)]
bench_all: bool,
/// Run benchmark for the IPC zero copy setup
#[clap(long)]
bench_ipc: bool,
/// Run benchmark for the process local setup
#[clap(long)]
bench_local: bool,
/// The greatest supported EventId
#[clap(short, long, default_value_t = EVENT_ID_MAX_VALUE)]
max_event_id: usize,
/// Activate full log output
#[clap(short, long)]
debug_mode: bool,
/// The cpu core that shall be used by thread 1
#[clap(long, default_value_t = 0)]
cpu_core_thread_1: usize,
/// The cpu core that shall be used by thread 2
#[clap(long, default_value_t = 1)]
cpu_core_thread_2: usize,
}

fn main() {
Expand All @@ -111,6 +132,21 @@ fn main() {
set_log_level(iceoryx2_bb_log::LogLevel::Info);
}

perform_benchmark::<ipc::Service>(&args);
perform_benchmark::<local::Service>(&args);
let mut at_least_one_benchmark_did_run = false;

if args.bench_ipc || args.bench_all {
perform_benchmark::<ipc::Service>(&args);
at_least_one_benchmark_did_run = true;
}

if args.bench_local || args.bench_all {
perform_benchmark::<local::Service>(&args);
at_least_one_benchmark_did_run = true;
}

if !at_least_one_benchmark_did_run {
println!(
"Please use either '--bench-all' or select a specific benchmark. See `--help` for details."
);
}
}
113 changes: 76 additions & 37 deletions benchmarks/publish-subscribe/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ use iceoryx2_bb_posix::thread::ThreadBuilder;

const ITERATIONS: u64 = 10000000;

fn perform_benchmark<T: Service>(iterations: u64) -> Result<(), Box<dyn std::error::Error>> {
fn perform_benchmark<T: Service>(args: &Args) -> Result<(), Box<dyn std::error::Error>> {
let service_name_a2b = ServiceName::new("a2b")?;
let service_name_b2a = ServiceName::new("b2a")?;
let node = NodeBuilder::new().create::<T>()?;

let service_a2b = node
.service_builder(&service_name_a2b)
.publish_subscribe::<u64>()
.publish_subscribe::<[u8]>()
.max_publishers(1)
.max_subscribers(1)
.history_size(0)
Expand All @@ -36,7 +36,7 @@ fn perform_benchmark<T: Service>(iterations: u64) -> Result<(), Box<dyn std::err

let service_b2a = node
.service_builder(&service_name_b2a)
.publish_subscribe::<u64>()
.publish_subscribe::<[u8]>()
.max_publishers(1)
.max_subscribers(1)
.history_size(0)
Expand All @@ -47,34 +47,63 @@ fn perform_benchmark<T: Service>(iterations: u64) -> Result<(), Box<dyn std::err
let barrier_handle = BarrierHandle::new();
let barrier = BarrierBuilder::new(3).create(&barrier_handle).unwrap();

let t1 = ThreadBuilder::new().affinity(0).priority(255).spawn(|| {
let sender_a2b = service_a2b.publisher_builder().create().unwrap();
let receiver_b2a = service_b2a.subscriber_builder().create().unwrap();

barrier.wait();

let mut sample = sender_a2b.loan().unwrap();

for _ in 0..iterations {
sample.send().unwrap();
sample = sender_a2b.loan().unwrap();
while receiver_b2a.receive().unwrap().is_none() {}
}
});

let t2 = ThreadBuilder::new().affinity(1).priority(255).spawn(|| {
let sender_b2a = service_b2a.publisher_builder().create().unwrap();
let receiver_a2b = service_a2b.subscriber_builder().create().unwrap();

barrier.wait();

for _ in 0..iterations {
let sample = sender_b2a.loan().unwrap();
while receiver_a2b.receive().unwrap().is_none() {}

sample.send().unwrap();
}
});
let t1 = ThreadBuilder::new()
.affinity(args.cpu_core_thread_1)
.priority(255)
.spawn(|| {
let sender_a2b = service_a2b
.publisher_builder()
.max_slice_len(args.payload_size)
.create()
.unwrap();
let receiver_b2a = service_b2a.subscriber_builder().create().unwrap();

barrier.wait();

let mut sample = unsafe {
sender_a2b
.loan_slice_uninit(args.payload_size)
.unwrap()
.assume_init()
};

for _ in 0..args.iterations {
sample.send().unwrap();
sample = unsafe {
sender_a2b
.loan_slice_uninit(args.payload_size)
.unwrap()
.assume_init()
};
while receiver_b2a.receive().unwrap().is_none() {}
}
});

let t2 = ThreadBuilder::new()
.affinity(args.cpu_core_thread_2)
.priority(255)
.spawn(|| {
let sender_b2a = service_b2a
.publisher_builder()
.max_slice_len(args.payload_size)
.create()
.unwrap();
let receiver_a2b = service_a2b.subscriber_builder().create().unwrap();

barrier.wait();

for _ in 0..args.iterations {
let sample = unsafe {
sender_b2a
.loan_slice_uninit(args.payload_size)
.unwrap()
.assume_init()
};
while receiver_a2b.receive().unwrap().is_none() {}

sample.send().unwrap();
}
});

std::thread::sleep(std::time::Duration::from_millis(100));
let start = Time::now().expect("failed to acquire time");
Expand All @@ -85,11 +114,12 @@ fn perform_benchmark<T: Service>(iterations: u64) -> Result<(), Box<dyn std::err

let stop = start.elapsed().expect("failed to measure time");
println!(
"{} ::: Iterations: {}, Time: {}, Latency: {} ns",
"{} ::: Iterations: {}, Time: {}, Latency: {} ns, Sample Size: {}",
std::any::type_name::<T>(),
iterations,
args.iterations,
stop.as_secs_f64(),
stop.as_nanos() / (iterations as u128 * 2)
stop.as_nanos() / (args.iterations as u128 * 2),
args.payload_size
);

Ok(())
Expand All @@ -113,6 +143,15 @@ struct Args {
/// Activate full log output
#[clap(short, long)]
debug_mode: bool,
/// The cpu core that shall be used by thread 1
#[clap(long, default_value_t = 0)]
cpu_core_thread_1: usize,
/// The cpu core that shall be used by thread 2
#[clap(long, default_value_t = 1)]
cpu_core_thread_2: usize,
/// The size in bytes of the payload that shall be used
#[clap(short, long, default_value_t = 8192)]
payload_size: usize,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
Expand All @@ -127,18 +166,18 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut at_least_one_benchmark_did_run = false;

if args.bench_ipc || args.bench_all {
perform_benchmark::<ipc::Service>(args.iterations)?;
perform_benchmark::<ipc::Service>(&args)?;
at_least_one_benchmark_did_run = true;
}

if args.bench_local || args.bench_all {
perform_benchmark::<local::Service>(args.iterations)?;
perform_benchmark::<local::Service>(&args)?;
at_least_one_benchmark_did_run = true;
}

if !at_least_one_benchmark_did_run {
println!(
"Please use either '--bench_all' or select a specific benchmark. See `--help` for details."
"Please use either '--bench-all' or select a specific benchmark. See `--help` for details."
);
}

Expand Down
2 changes: 1 addition & 1 deletion doc/release-notes/iceoryx2-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@

<!-- NOTE: Add new entries sorted by issue number to minimize the possibility of conflicts when merging. -->

* Example text [#1](https://github.com/eclipse-iceoryx/iceoryx2/issues/1)
* Extended CLI parameters for benchmarks [#360](https://github.com/eclipse-iceoryx/iceoryx2/issues/360)

### New API features

Expand Down
10 changes: 5 additions & 5 deletions internal/plots/benchmark_architecture_os_comparision.dat
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# System OS Latency
"Raspberry Pi 4B" "Linux" 875
"Intel i7-13700H" "Linux" 366
# System OS Latency Same Core Latency Different Cores
"Raspberry Pi 4B" "Linux" 875 0
"Intel i7-13700H" "Linux" 92 326
"Intel i7-8565U" "Linux" 238
"Intel i7-7500U" "Linux" 276
"AMD Ryzen 7 7840S" "Linux" 217
"AMD Ryzen 9 5950X" "Windows" 205
"AMD Ryzen 7 7840S" "Linux" 109 222
"AMD Ryzen 9 5950X" "Windows" 205
"AMD Ryzen 9 5950X" "Linux" 675

0 comments on commit 6089d60

Please sign in to comment.