-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
Benchmarking Zephyr vs. RIOT-OS #32875
Comments
Interesting results, thanks for sharing @luizvilla! Note that In the adc example, I'd use a hardware timer to trigger the ADC in a real application (it is possible on STM32). Regarding footprint sizes, it would be nice to compare rom reports in both cases to see the big difference, in particular for ADC and shell. Have you published any paper with some more insights? |
@luizvilla I've cloned your project, and I've seen a few things that can be disabled or improved. A few things: use minimal lib C (if possible by the application), disable some shell features, reduce some stack sizes, etc. Without testing on a real board I quickly got ~37K ROM and ~9K RAM by doing a few tweaks, so I'm sure there is room for improving the footprint at least. |
@luizvilla As mentionned by @gmarull, the first thing to do would be to understand the configuration used for the zephyr target. I guess this can be minimized in various ways, but point is to stay on par with RIOT configuration. For instance, on test_adc_g4, we can disable LOG, I2C, tweak stacks sizes, use minimal libc, and quickly divide footprint by 2. EDIT: Reached down to 17K/5K on |
You can see them here. As @gmarull pointed out, the set selected here is certainly not optimized in any way. |
I've seen that. I just want to know if this configuration was made on purpose, to be on par with RIOT configuration. |
@luizvilla Also, the project documentation to get the things build is great. Though, I haven't found info on how the latency measurements were made. Can you elaborate on this part ? |
I noticed that you are defining the trigger thread's priority to 6. Have you tried making this a high-prio cooperative thread instead? |
Thank you for your quick return!
The idea was to create a benchmark between both systems. So we did not try to optimize the code, but rather test equivalent functionality and performance for these functitonalities.
We toggle a pin and measure the time between toggles with different ranges of sleep from 0us to 10us.
Not really. We wanted to test if the threads had similar performances on comparable conditions. We are proofreading an internal report we made and we'll share with you as soon as we can. |
Sure, it's not about optimizing the code, but rather about defaults. If you want an apples to apples comparison you should enable the same features on both RTOS in my opinion. If it turns out that one of the two enables more functionality by default than the other one, then you should probably disable it in order to come to a meaningful comparison, unless you want to compare "default configurations". I suggest you use |
Agree with @carlescufi, a meaningful comparison should enable a comparable feature set on both sides. |
Thanks, everyone, for your valuable input.
We'll get back to you with more details. But I already thank you a lot for your reactivity and interest. |
Also, note the documentation for /*
* This function is unlikely to work as expected without kernel tuning.
* In particular, because the lower bound on the duration of a sleep is
* the duration of a tick, @option{CONFIG_SYS_CLOCK_TICKS_PER_SEC} must be
* adjusted to achieve the resolution desired. The implications of doing
* this must be understood before attempting to use k_usleep(). Use with
* caution.
*/ Zephyr's For small periods (Also, is Zephyr running in tickless mode? Is RIOT-OS? Are you running Zephyr with CONFIG_USERSPACE? Is the Zephyr thread preemptive? Is the RIOT-OS thread preemptive?) |
Yeah, looking at the code here, it seems like indeed the main loop is just asking for too much: https://gitlab.laas.fr/owntech/zephyr/-/blob/test_adc_g4/src/adc_g4/adc.c#L180 Zephyr's sleep calls are blocking primitives, they will register a timer interrupt for that duration in the future, pend the current thread, and then context switch to another thread (likely the idle thread in this app) to do other work while it waits. Trying to do that at > 30 kHz on a CPU like this isn't going to work well, your app is likely spending most of its time in context switch and interrupt handling. (It's also trying to do that more than twice as often as under RIOT). Similarly, I see you're asking for a tick rate of 1 MHz. That's not impossible to do as long as you configure 64 bit ticks, but in some sense that's false precision (on a 170 MHz CPU, it's going to take longer than 1us just to enter and exit the interrupt handler). Can you post the build/zephyr/.config file from your application? There is no doubt a ton of tuning we could suggest. |
OK, having studied the source to the test (and a tiny bit of digging in RIOT-OS), some more notes:
Broadly, I guess what I would hope to see here would be (given the ADC-sampling app), a comparison of the maximum sampling rate achievable under each OS under various IPC paradigms (sleeping, timer hooks, busy-waiting, etc...), and a statistical measure of each OS's variance (i.e. how regular are the sampling times). But the even shorter summary is that you really want to be using |
I will say though, that in RIOT-OS's defense their ARMv7 context switch code is a masterpiece of simplicity when compared with ours. It saves to the stack! It's local, no PendSV! No CONFIG_SWAP_NONATOMIC! It would make an excellent starting point for an arch_switch() if anyone wanted to try. I don't know that it's necessarily faster than our context switch code, but it's definitely cleaner. |
Thank you everyone for your returns! This has been super useful! |
Thanks @luizvilla! this is very interesting. Did you consider Contiki? |
I would suggest ADC reads using DMA to check the performance and ease of programming. Sampling a block at 48 kHz and then transferring it to the host while keeping up with all the work. Through how many hoops do you have to jump, to get this going with either Operating System. That would look at a real use case, while only using the shell before and after the measurements. You could also look at power management/drain for these use cases. |
Thanks @luizvilla to share this topic! Could you share the used code on Github? It seems the LAAS GitLab is not open to public access anymore. |
Hi, there @luizvilla! This was an interesting topic to read. But by any chance could you make the code public or maybe shared it somewhere else? I would really appreciate it. Thanks! |
Even though this discussion has been closed for more than 3 years, I really enjoyed the content 😄. |
Hello everyone,
I'm Luiz Villa, a researcher at the University of Toulouse. I'm working with software defined power converters and my team is looking into using an RTOS to manage real-time micro-controllers.
We ran a benchmark between Zephyr and RIOT OS that we would like to share with you.
Spoiler: Zephyr performed poorly.
Here's the summary:
Our test code is available at https://gitlab.laas.fr/owntech/zephyr/-/tree/test_adc_g4
Our target : Nucleo-G474RE
Our main conclusions:
Our questions for the community:
Originally posted by @luizvilla in #32870
The text was updated successfully, but these errors were encountered: