-
Notifications
You must be signed in to change notification settings - Fork 13.7k
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
uORB add bitset for faster orb_exists check and remove uORB::Subscription lazy subscribe hack/optimization #14106
Conversation
@julianoes @bkueng There's a bit more to do here to fix the RTPS build, but could you give this an initial pass? There are cleaner things we could do here if we're willing to drop C support, but I'll save that discussion for another day. I also have some ideas to build off of this for the next round of improvements towards the ultimate goal of uORB type and memory safety. |
Looks good from a first look at it - I'll still need to go through the details. |
TODO (in a followup PR later): store orb field names in a separate structure so that they can be GC'd in stripped down configurations that don't use logger or reply (eg CAN nodes #14148). |
9ecbf88
to
3a76f2d
Compare
The bitsets and testing were plucked from #11318. |
- add PX4 bitset and atomic_bitset with testing - add uORB::Subscription constructor to take ORB_ID enum - move orb test messages into msg/
3a76f2d
to
1c1930a
Compare
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.
Did you check the difference in boot time?
*/ | ||
extern const struct orb_metadata *const *orb_get_topics() __EXPORT; | ||
|
||
enum class ORB_ID : uint8_t { |
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.
Won't this cause troubles with the ORB_ID
macro? At the least it will be confusing.
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.
We can get away with it because of the parentheses, but I'm not sure how questionable it is. The idea is make them equivalent and interchangeable in most uORB usage and possibly transition entirely to the enum class version later.
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.
If we were ready/willing to drop orb C support entirely we could actually get rid of the ORB_ID macro as a wrapper for orb meta pointer (eg __orb_vehicle_status
) and replace it with a single byte enum class end-to-end.
Then ORB_ID(vehicle_status)
would simply give you ORB_ID::vehicle_status
.
Not accurately, but I wouldn't expect it to be noticeably different. What will be noticeable is the cpu usage is significantly lower immediately after boot compared to current master where it's hammering orb_exists heavily for the first 10-20 seconds. |
Tested on Pixhawk 4 v5Flight Card 1 Modes Tested: Procedure: Notes: Logs: https://review.px4.io/plot_app?log=e5f7fa23-0cc0-49bc-9579-1b8fc35eae76 Flight Card 2 Modes Tested Procedure Armed form QGC. Logs: https://review.px4.io/plot_app?log=d5245655-61d1-4a77-8120-b701c7f18793 Flight Card 3 Procedure Note: Logs: https://review.px4.io/plot_app?log=2b4c8524-f89c-4555-ad09-148ded67a646 Flight Card 4 Logs: |
Tested on PixRacer V4Flight Card 1 Modes Tested: Procedure: Notes: Logs: https://review.px4.io/plot_app?log=1266da62-77c8-4240-92e2-f252f816b4a4 Flight Card 2 Modes Tested Procedure Armed form QGC. Logs: https://review.px4.io/plot_app?log=e342b6a8-836d-4c27-9429-bd3c0e35ca10 Flight Card 3 Modes Tested Procedure Logs: https://review.px4.io/plot_app?log=249c19a1-aee7-4aad-90b5-c8188bf15de1 Flight Card 4 - Modes Tested Logs: https://review.px4.io/plot_app?log=9a17acc3-27d2-419a-aa04-a8824f4e06b8 Tested on CUAV nano V5Flight Card 1 Modes Tested: Procedure: Notes: Logs: https://review.px4.io/plot_app?log=501bba47-295e-41da-87e6-3d125338b5ff Flight Card 2 Modes Tested Procedure Armed form QGC. Logs: https://review.px4.io/plot_app?log=7a20f475-00d0-4d68-9b37-e62116082a20 Flight Card 3 Modes Tested Procedure Logs: https://review.px4.io/plot_app?log=9387a417-3dce-4a3a-83f9-9354b7f4ee53 Flight Card 4 - Modes Tested Logs: https://review.px4.io/plot_app?log=590db8a9-a5ea-491b-a0d3-5b169d487ea0 Tested on NXP V3Flight Card 1 Modes Tested: Procedure: Notes: Logs: https://review.px4.io/plot_app?log=16dd32ef-2f40-47dc-8b68-516c61d239be Flight Card 2 Modes Tested Procedure Armed form QGC. Logs: https://review.px4.io/plot_app?log=675540ad-aba5-4f77-b4b2-deca6c5b9606 Flight Card 3 Modes Tested Procedure Logs: https://review.px4.io/plot_app?log=97d4e29a-ba21-4b11-a476-0f3fb791251c Flight Card 4 - Modes Tested Logs: https://review.px4.io/plot_app?log=36d829a1-da6e-416c-9a82-edd433879ca1 |
Any other feedback? |
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.
Good to go from my side.
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.
Awesome! 🎉
Thanks everyone. |
🎉 thanks @dagar |
One of the inefficiencies in legacy
orb_subscribe()
addressed by the newuORB::Subscription
was that attempting to subscribe to a topic would create the underlying device node (the orb topic publication). As a result we had several kilobytes worth of unused orb device nodes in many setups.In
uORB::Subscription
we avoid this by checking if the publication actually exists (equivalent toorb_exists()
), however eachorb_exists()
call is relatively expensive. The short term optimization was to throttle the calls withinuORB::Subscription
after an initial 1000 attempts. The potential problem with this is a subscription might miss initial updates to topics that are only published late in flight.This PR makes those orb existence checks cheap enough we can use them in every single iteration by adding a bitset of atomic integers to the uORB DeviceMaster. Then I updated the orb generation to also create a class enum for ORB_IDs so that we have an index to use with the bitset.
Master (sensor_accel 0, 1, 2 exist, but 3 and 4 do not)
PR
In master
orb_exists()
for a topic that doesn't exist (with valid instance) is quite expensive because you have to search the entire list of topics. On fmu-v3 configured as a multicopter that's33.73 us
(average). With this PR that same check is1.61 us
. That might seem small, but it adds up across hundreds or even thousands of calls per second.Overall this saves a little bit of cpu (although quite a lot during the first 5-10 seconds of bootup) and a little bit of memory, despite increasing the size of the orb_metadata struct. More importantly it removes the possibility of subtle unexpected orb update behavior later in flight.