From 32f9f2f6922fefbc6a91ec82834a4e3bd73640b8 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 30 Jan 2025 08:56:58 +0100 Subject: [PATCH 1/5] [#610] Add configurable number of additional publishers/subscribers to pubsub benchmark --- benchmarks/publish-subscribe/src/main.rs | 31 ++++++++++++++++++++---- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/benchmarks/publish-subscribe/src/main.rs b/benchmarks/publish-subscribe/src/main.rs index ef4632e69..f86780d8e 100644 --- a/benchmarks/publish-subscribe/src/main.rs +++ b/benchmarks/publish-subscribe/src/main.rs @@ -29,8 +29,8 @@ fn perform_benchmark(args: &Args) -> Result<(), Box() - .max_publishers(1) - .max_subscribers(1) + .max_publishers(1 + args.number_of_additional_publishers) + .max_subscribers(1 + args.number_of_additional_subscribers) .history_size(0) .subscriber_max_buffer_size(1) .enable_safe_overflow(true) @@ -39,13 +39,26 @@ fn perform_benchmark(args: &Args) -> Result<(), Box() - .max_publishers(1) - .max_subscribers(1) + .max_publishers(1 + args.number_of_additional_publishers) + .max_subscribers(1 + args.number_of_additional_subscribers) .history_size(0) .subscriber_max_buffer_size(1) .enable_safe_overflow(true) .create()?; + let mut additional_publishers = Vec::new(); + let mut additional_subscribers = Vec::new(); + + for _ in 0..args.number_of_additional_publishers { + additional_publishers.push(service_a2b.publisher_builder().create()?); + additional_publishers.push(service_b2a.publisher_builder().create()?); + } + + for _ in 0..args.number_of_additional_subscribers { + additional_subscribers.push(service_a2b.subscriber_builder().create()?); + additional_subscribers.push(service_b2a.subscriber_builder().create()?); + } + let start_benchmark_barrier_handle = BarrierHandle::new(); let startup_barrier_handle = BarrierHandle::new(); let startup_barrier = BarrierBuilder::new(3) @@ -175,8 +188,16 @@ struct Args { /// The size in bytes of the payload that shall be used #[clap(short, long, default_value_t = 8192)] payload_size: usize, + /// Send a copy of the payload instead of performing true zero-copy. Can provide an hint on + /// how expensive serialization can be. #[clap(long)] send_copy: bool, + /// The number of additional publishers per service in the setup. + #[clap(long, default_value_t = 0)] + number_of_additional_publishers: usize, + /// The number of additional subscribers per service in the setup. + #[clap(long, default_value_t = 0)] + number_of_additional_subscribers: usize, } fn main() -> Result<(), Box> { @@ -185,7 +206,7 @@ fn main() -> Result<(), Box> { if args.debug_mode { set_log_level(iceoryx2_bb_log::LogLevel::Trace); } else { - set_log_level(iceoryx2_bb_log::LogLevel::Info); + set_log_level(iceoryx2_bb_log::LogLevel::Error); } let mut at_least_one_benchmark_did_run = false; From 1e76a912c63f04c325f6821bb4861e7da2358048 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 30 Jan 2025 09:14:21 +0100 Subject: [PATCH 2/5] [#610] Add configurable number of additional notifiers/listeners to event benchmark --- benchmarks/event/src/main.rs | 47 +++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/benchmarks/event/src/main.rs b/benchmarks/event/src/main.rs index 93cff44af..4ae3ab431 100644 --- a/benchmarks/event/src/main.rs +++ b/benchmarks/event/src/main.rs @@ -17,16 +17,16 @@ use iceoryx2_bb_posix::barrier::*; use iceoryx2_bb_posix::clock::Time; use iceoryx2_bb_posix::thread::ThreadBuilder; -fn perform_benchmark(args: &Args) { - let service_name_a2b = ServiceName::new("a2b").unwrap(); - let service_name_b2a = ServiceName::new("b2a").unwrap(); - let node = NodeBuilder::new().create::().unwrap(); +fn perform_benchmark(args: &Args) -> Result<(), Box> { + let service_name_a2b = ServiceName::new("a2b")?; + let service_name_b2a = ServiceName::new("b2a")?; + let node = NodeBuilder::new().create::()?; let service_a2b = node .service_builder(&service_name_a2b) .event() - .max_notifiers(1) - .max_listeners(1) + .max_notifiers(1 + args.number_of_additional_notifiers) + .max_listeners(1 + args.number_of_additional_listeners) .event_id_max_value(args.max_event_id) .create() .unwrap(); @@ -34,12 +34,25 @@ fn perform_benchmark(args: &Args) { let service_b2a = node .service_builder(&service_name_b2a) .event() - .max_notifiers(1) - .max_listeners(1) + .max_notifiers(1 + args.number_of_additional_notifiers) + .max_listeners(1 + args.number_of_additional_listeners) .event_id_max_value(args.max_event_id) .create() .unwrap(); + let mut additional_notifiers = Vec::new(); + let mut additional_listeners = Vec::new(); + + for _ in 0..args.number_of_additional_notifiers { + additional_notifiers.push(service_a2b.notifier_builder().create()?); + additional_notifiers.push(service_b2a.notifier_builder().create()?); + } + + for _ in 0..args.number_of_additional_listeners { + additional_listeners.push(service_a2b.listener_builder().create()?); + additional_listeners.push(service_b2a.listener_builder().create()?); + } + let start_benchmark_barrier_handle = BarrierHandle::new(); let startup_barrier_handle = BarrierHandle::new(); let startup_barrier = BarrierBuilder::new(3) @@ -99,6 +112,8 @@ fn perform_benchmark(args: &Args) { stop.as_secs_f64(), stop.as_nanos() / (args.iterations as u128 * 2) ); + + Ok(()) } const ITERATIONS: usize = 1000000; @@ -131,26 +146,32 @@ struct Args { /// The cpu core that shall be used by participant 2 #[clap(long, default_value_t = 1)] cpu_core_participant_2: usize, + /// The number of additional notifiers per service in the setup. + #[clap(long, default_value_t = 0)] + number_of_additional_notifiers: usize, + /// The number of additional listeners per service in the setup. + #[clap(long, default_value_t = 0)] + number_of_additional_listeners: usize, } -fn main() { +fn main() -> Result<(), Box> { let args = Args::parse(); if args.debug_mode { set_log_level(iceoryx2_bb_log::LogLevel::Trace); } else { - set_log_level(iceoryx2_bb_log::LogLevel::Info); + set_log_level(iceoryx2_bb_log::LogLevel::Error); } let mut at_least_one_benchmark_did_run = false; if args.bench_ipc || args.bench_all { - perform_benchmark::(&args); + perform_benchmark::(&args)?; at_least_one_benchmark_did_run = true; } if args.bench_local || args.bench_all { - perform_benchmark::(&args); + perform_benchmark::(&args)?; at_least_one_benchmark_did_run = true; } @@ -159,4 +180,6 @@ fn main() { "Please use either '--bench-all' or select a specific benchmark. See `--help` for details." ); } + + Ok(()) } From 9624ccf2ed97e86f68588ad60344233fd91e5009 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 30 Jan 2025 09:14:33 +0100 Subject: [PATCH 3/5] [#610] Update event benchmark readme --- benchmarks/README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/benchmarks/README.md b/benchmarks/README.md index 8ac7cd6a8..0616bbcce 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -38,6 +38,28 @@ For more benchmark configuration details, see cargo run --bin benchmark-event --release -- --help ``` +> [!IMPORTANT] +> When you increase the number of listeners or notifiers beyond a certain limit, +> the benchmark may exceed the per-user file descriptor limit. This limit can be +> increased by adjusting the `nofile` setting in the `/etc/security/limits.conf` +> file: +> +> ```ascii +> * soft nofile 4096 +> * hard nofile 8192 +> ``` +> +> * `*` – Applies to all users +> * `soft` | `hard` – The soft and hard limits +> * The soft limit is set to 4096, while the hard limit is set to 8192 +> +> After making these changes, you can use the following command to increase the +> soft file descriptor limit up to the hard limit: +> +> ```bash +> ulimit -n +> ``` + ## Queue The queue quantifies the latency between pushing an element into a queue and From 9aa6f8fb2c9c738075d902848585ea4da5b723cd Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 30 Jan 2025 09:19:21 +0100 Subject: [PATCH 4/5] [#610] Update FAQ --- FAQ.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/FAQ.md b/FAQ.md index bd4e82c22..62b08f54f 100644 --- a/FAQ.md +++ b/FAQ.md @@ -209,3 +209,28 @@ let publisher = service All these parameters can also be set globally by using the [iceoryx2 config file](config). + +## `Error: Resource Creation Failed` + +### You May Exceeded The Maximum File-Descriptor Limit + +When you increase the number of services or ports beyond a certain limit for +one process, the process may exceed the per-user file descriptor limit. This +limit can be increased by adjusting the `nofile` setting in the +`/etc/security/limits.conf` file: + +```ascii +* soft nofile 4096 +* hard nofile 8192 +``` + +* `*` – Applies to all users +* `soft` | `hard` – The soft and hard limits +* The soft limit is set to 4096, while the hard limit is set to 8192 + +After making these changes, you can use the following command to increase the +soft file descriptor limit up to the hard limit: + +```bash +ulimit -n +``` From 49c288ec0344451ab380acd07f8ab597623154f1 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 30 Jan 2025 09:23:12 +0100 Subject: [PATCH 5/5] [#610] Update changelog --- doc/release-notes/iceoryx2-unreleased.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/release-notes/iceoryx2-unreleased.md b/doc/release-notes/iceoryx2-unreleased.md index b964882bf..ea786d7c9 100644 --- a/doc/release-notes/iceoryx2-unreleased.md +++ b/doc/release-notes/iceoryx2-unreleased.md @@ -21,6 +21,8 @@ [#579](https://github.com/eclipse-iceoryx/iceoryx2/issues/579) * Use 'std_instead_of_alloc' and 'alloc_instead_of_core' clippy warning [#581](https://github.com/eclipse-iceoryx/iceoryx2/issues/581) +* Extend benchmarks to test setups with multiple sending/receiving ports + [#610](https://github.com/eclipse-iceoryx/iceoryx2/issues/610) ### Bugfixes