-
Notifications
You must be signed in to change notification settings - Fork 116
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
Be more proactive about skipping work if possible #685
Conversation
@@ -49,6 +49,9 @@ find_package(fastcdr REQUIRED CONFIG) | |||
find_package(fastrtps 2.3 REQUIRED CONFIG) | |||
find_package(FastRTPS 2.3 REQUIRED MODULE) | |||
|
|||
find_package(Threads REQUIRED) | |||
find_package(tracy_vendor REQUIRED) |
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.
What's with the tracy_vendor
here? Do we need this to get this work in?
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.
No, there are some profiling points in this branch, I will remove for final merge if we determine this is a valid approach.
@MiguelCompany I am also looking at adding a method to the waitset to allow attaching/detaching multiple conditions. I think this can save a bit of churn in locking/unlocking mutexes: https://github.com/mjcarroll/Fast-DDS/tree/mjcarroll/attach_multiple_conditions |
Signed-off-by: Michael Carroll <michael@openrobotics.org>
388712d
to
d8d95de
Compare
Signed-off-by: Michael Carroll <michael@openrobotics.org> Co-authored-by: Miguel Company <miguelcompany@eprosima.com>
Signed-off-by: Michael Carroll <michael@openrobotics.org>
d8d95de
to
ce5f9a2
Compare
@clalancette this one is ready for you. |
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.
I've left just a few nits inline. All of these are small enough that a "it compiles for me" comment is good enough so we don't have to restart CI.
I went through this with @mjcarroll in some detail. In short, what this does is to change it so that we no longer call wait_set->wait()
if there is already work waiting for us. If that is the case, then we also don't need to attach/detach conditions to the wait_set if we already have work, and we can just go through and null out the entries that don't have work waiting. If we do have work waiting for us, then we need to do the whole dance.
I will note that this is much faster in the best case, where the first guard condition we are waiting on is triggered. In that case, we'll do much less work than before. However, if there is no work for us to do, then this is actually somewhat slower than before since we need to iterate over the lists 3 times instead of 2. I think this is an acceptable tradeoff for now, but it bears looking into further to see if we can reduce how expensive get_first_untaken_info
is.
Anyway, with my nits fixed, I'm happy to approve this. It looks like a net win for now.
if (!skip_wait) { | ||
timeout = (wait_timeout) ? | ||
// Attach all of the conditions to the wait set. | ||
// \TODO(mjcarroll) When upstream has the ability to attach a vector of conditions, |
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.
// \TODO(mjcarroll) When upstream has the ability to attach a vector of conditions, | |
// TODO(mjcarroll): When upstream has the ability to attach a vector of conditions, |
wait_result = (ret_code == ReturnCode_t::RETCODE_OK); | ||
|
||
// Detach all of the conditions from the wait set. | ||
// \TODO(mjcarroll) When upstream has the ability to detach a vector of conditions, |
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.
// \TODO(mjcarroll) When upstream has the ability to detach a vector of conditions, | |
// TODO(mjcarroll): When upstream has the ability to detach a vector of conditions, |
* \param[in] events events to check | ||
* \return true if any condition is triggered, false otherwise | ||
*/ | ||
bool has_triggered_condition( |
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.
bool has_triggered_condition( | |
static bool has_triggered_condition( |
(or an anonymous namespace, I really don't have a preference)
auto custom_subscriber_info = static_cast<CustomSubscriberInfo *>(data); | ||
eprosima::fastdds::dds::SampleInfo sample_info; | ||
if (ReturnCode_t::RETCODE_OK == | ||
custom_subscriber_info->data_reader_->get_first_untaken_info(&sample_info)) |
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.
I think it is worthwhile to add a comment saying that this is relatively slow, so it is worth skipping it if possible.
Based on my testing with https://github.com/irobot-ros/ros2-performance, there is less tradeoff than you would think at first. We do add a second set of iterations before the In the case that there is something already ready, we skip attaching the conditions, which are somewhat expensive (each requires a lock and unlock of a mutex) as well as skipping the |
Two potential enhancements here (but out of the scope of this PR):
|
Signed-off-by: Michael Carroll <michael@openrobotics.org>
Alright, everything but Windows debug is green, so I'm calling this good. |
In the case that a condition is already triggered, skip attaching/detaching conditions as well as the actual wait call. This reduces call time in many cases where work is already queued. Signed-off-by: Michael Carroll <michael@openrobotics.org> Co-authored-by: Miguel Company <miguelcompany@eprosima.com>
This makes
rmw_wait
more aggressive about how it skips work.In the case that a condition is already met, this will skip attaching/detaching conditions from the underlying waitset and skip waiting.
In the case that a wait is required, it generally looks like this:
![image](https://user-images.githubusercontent.com/279701/230673405-79e16c40-d8c7-445c-a688-46a7a5ef5d70.png)
and when a wait isn't needed: