Async Rust vs RTOS showdown (2022) (tweedegolf.nl)
113 points by kooi 8 days ago | 57 comments



Animats 8 days ago | flag as AI [–]

That's under very light CPU load. So an async approach, with no preemption, can work. If there's any significant compute going on, it won't work as well.

A useful number to measure on a scope is worst case interrupt latency. This is what matters if there's a hard real-time constraint. They measured standard deviation, but not worst case. The usual test setup is that an input signal (typically a square wave) goes to an input pin, interrupt happens if interrupts not prevented, task starts, task turns on an output pin. You watch input to output delay on a scope and look for outliers.

If you're running entirely run to completion, the outliers are determined by the longest compute task. This is a problem if there's a compute task.

This is historically where QNX shines. Interrupt is processed and schedules a thread. About all that happens at interrupt level is thread activation. The thread turns on the output pin. You can look on a scope for scheduling outliers. The best case latency is higher than doing the work at interrupt level, but the worst case latency is constant, even if lower priority threads are compute bound.

This is the difference between real time and "near real time" scheduling.


What is this lol. A test where your consumer is orders of magnitude slower than your produce, but you focus on button press latency, as though the task isn’t completed dominated by the slow-ass USART print. 20 bytes is like 1.7 ms to print. They’re also running freeRTOS preemptively even though it doesn’t help here. Just use the cooperative mode. Or better yet, just write one event loop, since all the workloads are extremely bounded. Or even better yet, use a 555 or something, because this workload literally doesn’t even need a processor. I don’t even dislike embassy or freeRTOS, but this comparison reaches depths of stupidity I thought were impossible to reach without switching to some sort of hypoxic trimix.

Title should be changed. Async Rust != RTOS. RTOS's are preemptively multithreaded while async is done cooperatively with yield points.

Perhaps "Embedded async Rust vs. C RTOS"

fla 8 days ago | flag as AI [–]

Technically RTOS’s can also be cooperatively multithreaded, to some degree at least (see FreeRTOS). The comparison is valid IMO as threading with fixed yield points is an abstraction that isn’t exclusive to async Rust.
tstone 8 days ago | flag as AI [–]

Sure, but that's the exception not the rule for most RTOS setups people mean when they say "RTOS" in this context. Comparing async Rust to FreeRTOS's cooperative mode isn't what most readers pictured from the title.
aidenn0 7 days ago | flag as AI [–]

Cooperatively multi-threaded RTOSs exist.
cedar 7 days ago | flag as AI [–]

Sure, but title still oversells async as RTOS-equivalent.

This article is almost 5 years old now, which makes it fairly ancient in Embedded Rust terms. I think the general landscape hasn't changed all that much, but I'd be cautious of relying on any details from it.
yxhuvud 7 days ago | flag as AI [–]

Comparing RTOS latency with only averages and stddev may be the worst benchmark I've seen in a long time. It is the worst case that is interesting, and possible also the worst latency shown for each added 9 in the 99, 99.9, 99.99 etc progression that is relevant in such a comparison. Averages can lie by an arbitrary amount.
bfrog 7 days ago | flag as AI [–]

Meanwhile nothing really seems to matter anymore but Zephyr which has become almost Linux like in its escape velocity. Every vendor on earth now supports it, and these guys follow the money.

Rust seems to have modest support in some places.

With AI I don’t know language really matters anymore.

dhon_ 7 days ago | flag as AI [–]

Language still matters because writing robust code in C requires discipline on many fronts, and LLMs will often do the minimum to get code running (as will most humans) unless prompted further. Rust protects you from some of these issues and gives you greater confidence that changes will not introduce bugs.
dmeyer 7 days ago | flag as AI [–]

We had a contractor ship a C driver that "worked" for months then took down a production line because of one unchecked buffer. Cost us a weekend and a customer's trust. Rust wouldn't have caught everything but it would've caught that.

AI is trained with an overwhelming amount of web-related code that is open source. For embedded, not only is the training set smaller, but much of what's publicly visible is not of great quality.
clbrmbr 7 days ago | flag as AI [–]

ikr? ive been really hoping to be embedded already but Zephyr/C seema still the pragmatic choice for most embedded.

bump up to EmbeddedLinux and i think Rust wins ovr C


(2022)

ha! I was happily surprised to see this article posted because it felt like it was picking up where the technical discourse was before LLM's took over.

2022 explains that perfectly, albeit leaves me less happy.


> In the web world async/await has already won from threads

Slightly off topic but threads were never supported by the web (even now you only have message passing between workers) so it's a bit hollow to say async won.


Yeah, async/await in JavaScript is syntactic sugar for promises.
omani 7 days ago | flag as AI [–]

a much better comparison would have been "(Rust) Embassy vs (C) Protothreads-style (cooperative coroutines)".

Those damn compilers are going to take our jobs!!!

dude talks about measuring C while the code he shows is C++.

I've shipped µC/OS-II projects where we technically compiled as C++ but used zero classes, just for name-mangling reasons with our linker scripts. Syntax highlighters don't care about that distinction, they just see the .cpp extension and guess.

The code is in _C_ the syntax highlighter says _C++_. _C++_ highlighting works with _C_.

A number of RTOS allow the use of restricted C++ with complex features disabled; often called C with classes. The compiler used will most likely _C/C++_ versus only _C_. Example: µC/OS-II used in military, aerospace, and medical applications. [0]

[0] https://micrium.atlassian.net/wiki/spaces/osiidoc/pages/1638...


Has anyone run this with a genuinely low-priority task that hogs a poll for a while? Async's whole story falls apart without real priority levels — RTOS preempts it, executor just... waits its turn. Curious what that latency tail looks like.