-
Notifications
You must be signed in to change notification settings - Fork 61
[#139] events with bitset #167
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
Changes from 7 commits
bbeac8a
f405333
88886bf
998916b
ed3da85
61876fb
6bd832c
61669e0
bf7e68e
4987d65
41ab76e
e3698e0
4b70a15
e6c5133
79ea3cb
e29d53a
66d1d78
668321d
93778cd
998bfe9
b4f3687
9db4b1e
99d056a
021142e
6f7ab35
bd6a1de
9ca036a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[package] | ||
name = "benchmark-event" | ||
description = "iceoryx2: [internal] benchmark for the iceoryx2 event services" | ||
categories = { workspace = true } | ||
edition = { workspace = true } | ||
homepage = { workspace = true } | ||
keywords = { workspace = true } | ||
license = { workspace = true } | ||
repository = { workspace = true } | ||
rust-version = { workspace = true } | ||
version = { workspace = true } | ||
|
||
[dependencies] | ||
iceoryx2 = { workspace = true } | ||
iceoryx2-bb-log = { workspace = true } | ||
|
||
clap = { workspace = true } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// Copyright (c) 2024 Contributors to the Eclipse Foundation | ||
// | ||
// See the NOTICE file(s) distributed with this work for additional | ||
// information regarding copyright ownership. | ||
// | ||
// This program and the accompanying materials are made available under the | ||
// terms of the Apache Software License 2.0 which is available at | ||
// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license | ||
// which is available at https://opensource.org/licenses/MIT. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
|
||
use std::{sync::Barrier, time::Instant}; | ||
|
||
use clap::Parser; | ||
use iceoryx2::prelude::*; | ||
use iceoryx2_bb_log::set_log_level; | ||
|
||
fn perform_benchmark<T: Service>(args: &Args) { | ||
let service_name_a2b = ServiceName::new("a2b").unwrap(); | ||
let service_name_b2a = ServiceName::new("b2a").unwrap(); | ||
|
||
let service_a2b = T::new(&service_name_a2b) | ||
.event() | ||
.max_notifiers(1) | ||
.max_listeners(1) | ||
.create() | ||
.unwrap(); | ||
|
||
let service_b2a = T::new(&service_name_b2a) | ||
.event() | ||
.max_notifiers(1) | ||
.max_listeners(1) | ||
.create() | ||
.unwrap(); | ||
|
||
let barrier = Barrier::new(3); | ||
|
||
std::thread::scope(|s| { | ||
let t1 = s.spawn(|| { | ||
let notifier_a2b = service_a2b.notifier().create().unwrap(); | ||
let mut listener_b2a = service_b2a.listener().create().unwrap(); | ||
|
||
barrier.wait(); | ||
notifier_a2b.notify().expect("failed to notify"); | ||
|
||
for _ in 0..args.iterations { | ||
while listener_b2a.blocking_wait().unwrap().is_empty() {} | ||
notifier_a2b.notify().expect("failed to notify"); | ||
} | ||
}); | ||
|
||
let t2 = s.spawn(|| { | ||
let notifier_b2a = service_b2a.notifier().create().unwrap(); | ||
let mut listener_a2b = service_a2b.listener().create().unwrap(); | ||
|
||
barrier.wait(); | ||
for _ in 0..args.iterations { | ||
while listener_a2b.blocking_wait().unwrap().is_empty() {} | ||
notifier_b2a.notify().expect("failed to notify"); | ||
} | ||
}); | ||
|
||
std::thread::sleep(std::time::Duration::from_millis(100)); | ||
let start = Instant::now(); | ||
barrier.wait(); | ||
|
||
t1.join().expect("thread failure"); | ||
t2.join().expect("thread failure"); | ||
|
||
let stop = start.elapsed(); | ||
println!( | ||
"{} ::: Iterations: {}, Time: {}, Latency: {} ns", | ||
std::any::type_name::<T>(), | ||
args.iterations, | ||
stop.as_secs_f64(), | ||
stop.as_nanos() / (args.iterations as u128 * 2) | ||
); | ||
}); | ||
} | ||
|
||
const ITERATIONS: usize = 1000000; | ||
const CAPACITY: usize = 128; | ||
|
||
#[derive(Parser, Debug)] | ||
#[clap(version, about, long_about = None)] | ||
struct Args { | ||
/// Number of iterations the A --> B --> A communication is repeated | ||
#[clap(short, long, default_value_t = ITERATIONS)] | ||
iterations: usize, | ||
/// Capacity of the bitset | ||
#[clap(short, long, default_value_t = CAPACITY)] | ||
capacity: usize, | ||
} | ||
|
||
fn main() { | ||
let args = Args::parse(); | ||
set_log_level(iceoryx2_bb_log::LogLevel::Error); | ||
|
||
perform_benchmark::<zero_copy::Service>(&args); | ||
perform_benchmark::<process_local::Service>(&args); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,7 @@ | |
pub mod details { | ||
use std::{fmt::Debug, marker::PhantomData, time::Duration}; | ||
|
||
use iceoryx2_bb_log::fail; | ||
use iceoryx2_bb_log::{debug, fail}; | ||
use iceoryx2_bb_memory::bump_allocator::BumpAllocator; | ||
use iceoryx2_bb_system_types::{file_name::FileName, path::Path}; | ||
|
||
|
@@ -32,7 +32,7 @@ pub mod details { | |
}, | ||
}; | ||
|
||
const TRIGGER_ID_DEFAULT_MAX: TriggerId = TriggerId::new(u16::MAX as u64); | ||
const TRIGGER_ID_DEFAULT_MAX: TriggerId = TriggerId::new(u16::MAX as _); | ||
|
||
#[derive(Debug)] | ||
pub struct Management<Tracker: IdTracker, WaitMechanism: SignalMechanism> { | ||
|
@@ -383,6 +383,7 @@ pub mod details { | |
fn try_wait( | ||
&self, | ||
) -> Result<Option<crate::event::TriggerId>, crate::event::ListenerWaitError> { | ||
// collect all notifications until no more are available | ||
while unsafe { self.storage.get().signal_mechanism.try_wait()? } {} | ||
elfenpiff marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Ok(unsafe { self.storage.get().id_tracker.acquire() }) | ||
} | ||
|
@@ -395,11 +396,14 @@ pub mod details { | |
return Ok(Some(id)); | ||
} | ||
|
||
if unsafe { self.storage.get().signal_mechanism.timed_wait(timeout)? } { | ||
return Ok(unsafe { self.storage.get().id_tracker.acquire() }); | ||
} | ||
|
||
Ok(None) | ||
Ok(unsafe { | ||
self.storage | ||
.get() | ||
.signal_mechanism | ||
.timed_wait(timeout)? | ||
.then_some(self.storage.get().id_tracker.acquire()) | ||
.flatten() | ||
}) | ||
} | ||
|
||
fn blocking_wait( | ||
|
@@ -459,10 +463,13 @@ pub mod details { | |
mgmt: &mut Management<Tracker, WaitMechanism>, | ||
allocator: &mut BumpAllocator, | ||
) -> bool { | ||
let origin = "init()"; | ||
if unsafe { mgmt.id_tracker.init(allocator).is_err() } { | ||
debug!(from origin, "Unable to initialize IdTracker."); | ||
return false; | ||
} | ||
if unsafe { mgmt.signal_mechanism.init().is_err() } { | ||
debug!(from origin, "Unable to initialize SignalMechanism."); | ||
return false; | ||
} | ||
|
||
|
@@ -489,7 +496,7 @@ pub mod details { | |
ListenerCreateError, | ||
> { | ||
let msg = "Failed to create Listener"; | ||
let id_tracker_capacity = self.trigger_id_max.as_u64() as usize; | ||
let id_tracker_capacity = self.trigger_id_max.as_u64() as usize + 1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why the +1 here and teh -1 in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I realized that I assumed that To support all ids up to - including - trigger id max, the bitset requires a capacity of + 1 and the trigger id max on the other side is then capacity - 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So it acts kind of like an |
||
|
||
match Storage::Builder::new(&self.name) | ||
.config(&self.config.convert()) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it is possible that the OS does not schedule you anymore after the wait call and then you start measuring too late and the numbers are in your favor. So I wanted to be a bit more pessimistic here.
I do the same thing in the publish-subscribe benchmark
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case two barriers can be used to get rid of the sleep and make it more deterministic ... just a suggestion, not action required