Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#610] extend benchmarks #611

Merged
merged 5 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <new_limit>
```
22 changes: 22 additions & 0 deletions benchmarks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <new_limit>
> ```

## Queue

The queue quantifies the latency between pushing an element into a queue and
Expand Down
47 changes: 35 additions & 12 deletions benchmarks/event/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,42 @@ use iceoryx2_bb_posix::barrier::*;
use iceoryx2_bb_posix::clock::Time;
use iceoryx2_bb_posix::thread::ThreadBuilder;

fn perform_benchmark<T: Service>(args: &Args) {
let service_name_a2b = ServiceName::new("a2b").unwrap();
let service_name_b2a = ServiceName::new("b2a").unwrap();
let node = NodeBuilder::new().create::<T>().unwrap();
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)
.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 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)
Expand Down Expand Up @@ -99,6 +112,8 @@ fn perform_benchmark<T: Service>(args: &Args) {
stop.as_secs_f64(),
stop.as_nanos() / (args.iterations as u128 * 2)
);

Ok(())
}

const ITERATIONS: usize = 1000000;
Expand Down Expand Up @@ -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<dyn std::error::Error>> {
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::<ipc::Service>(&args);
perform_benchmark::<ipc::Service>(&args)?;
at_least_one_benchmark_did_run = true;
}

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

Expand All @@ -159,4 +180,6 @@ fn main() {
"Please use either '--bench-all' or select a specific benchmark. See `--help` for details."
);
}

Ok(())
}
31 changes: 26 additions & 5 deletions benchmarks/publish-subscribe/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ fn perform_benchmark<T: Service>(args: &Args) -> Result<(), Box<dyn std::error::
let service_a2b = node
.service_builder(&service_name_a2b)
.publish_subscribe::<[u8]>()
.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)
Expand All @@ -39,13 +39,26 @@ fn perform_benchmark<T: Service>(args: &Args) -> Result<(), Box<dyn std::error::
let service_b2a = node
.service_builder(&service_name_b2a)
.publish_subscribe::<[u8]>()
.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)
Expand Down Expand Up @@ -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<dyn std::error::Error>> {
Expand All @@ -185,7 +206,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
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;
Expand Down
2 changes: 2 additions & 0 deletions doc/release-notes/iceoryx2-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down