Earlier quoted context omitted.
As you mentioned Java, it’s interesting to notice that it has had similar problems throughout its history: logging (now it’s settled on slf4j but you still find libraries using something else), commons (first Apache Commons, now Guava), JSON (it has settled on Jackson but things like Gson and Simple-json are not uncommon to see), nullability annotations ( first with unofficial distributions of JSR-305 which never bec…
But this fragmentation is what needed to make good software. If you put things in the standard library you're just adding a +1 to the fragmented landscape because for instance it will never be specialized enough to cover all use cases, so people will still use their own libraries, just like for instance c++ has three dozen distinct implementations of hash maps just because one cannot fit all cases
Async Rust never left the MVP state
171–180 of 273 posts
Re: Async Rust never left the MVP state
#172Great article! Love these types of deep dives into optimizations. Hope the project goal works out! I've felt before that compilers often don't put much effort into optimizing the "trivial" cases. Overly dramatic title for the content, though. I would have clicked "Async Rust Optimizations the Compiler Still Misses" too you know
So on the title, I picked this because it's simply the truth. Since async landed in 2019 or so, not much has changed. Yes, we can have async in traits and closures now. But those are updates to the typesystem, not to the async machinery itself. Wakers are a little bit easier to work with, but that's an update to std/core. As I understand it, the people who landed async Rust were quite burnt out and got less active an…
Re: Async Rust never left the MVP state
#173Earlier quoted context omitted.
> Retrospectively, i think everyone is satisfied with the adopted syntax. Maybe it’s a case of agree and commit, since it can’t really be walked back.
Various prominent people have said years after that .await was the correct choice after all
Re: Async Rust never left the MVP state
#174Async seems like an underbaked idea across the board. Regular code was already async. When you need to wait for an async operation, the thread sleeps until ready and the kernel abstracts it away. But We didn’t like structuring code into logical threads, so we added callback systems for events. Then realized callbacks are very hard to reason about and that sequential control is better. So threads was the right program…
It depends on what you are doing. Threads are the right model for compute-bound workloads. Async is the right model for bandwidth-bound workloads.
Optimization of bandwidth-bound code is an exercise in schedule design. In a classic multithreading model you have limited control over scheduling. In an async model you can have almost perfect control over scheduling. A well-optimized async schedule is much faster than the equivalent multithreaded architecture for the same bandwidth-bound workload. It isn't even close.
Most high-performance code today is bandwidth-bound. Async exists to make optimization of these workloads easier.
Re: Async Rust never left the MVP state
#175Async seems like an underbaked idea across the board. Regular code was already async. When you need to wait for an async operation, the thread sleeps until ready and the kernel abstracts it away. But We didn’t like structuring code into logical threads, so we added callback systems for events. Then realized callbacks are very hard to reason about and that sequential control is better. So threads was the right program…
Re: Async Rust never left the MVP state
#176Earlier quoted context omitted.
Various prominent people have said years after that .await was the correct choice after all
I'm not prominent but I disagreed with it at the time and I was wrong.
Re: Async Rust never left the MVP state
#177Earlier quoted context omitted.
What's the alternative? I'm happy to use tokio, but i'm happy other folks can enjoy other executors (smol, async-std, glommio, etc). I think the situation is OK because tokio is well-maintained, even though it's not part of the standard library, and i'm afraid making it part of the standard library would make it harder to use other executors, and harder to port the standard library to other platforms. But maybe my fe…
Here are some alternatives for concurrent operations in rust that don't use Async. Which are available depend on the target, e.g. embedded/low-level vs GPOS. I use all of these across my Rust projects: - Threads and thread pools - CPU SIMD - GPU - DMA, with memory and/or dedicated hardcore - Multiple cores, ICs, or MCUs - Hardware interrupts - Event loops Most of you are already aware. I bring this up because I have…
The hardest parts for me to grok really came down to lifetime memory management, for example a static/global dictionary as a cache, but being able to evict/recover entries from that dictionary for expired data... This is probably the use case that IMO is one of the least well documented, or at least lacking in discoverable tutorials etc.
Re: Async Rust never left the MVP state
#178async fn bar(input: u32) -> i32 { let blah = input > 10; // Preamble let result = foo(blah).await; result * 2 // Postamble } > If only we were allowed to execute the code up to the first await point, then we could get rid of the Unresumed state. But "futures don't do anything unless polled" is guaranteed, so we can't change that. Is that actually valid reasoning? If we know that foo(blah) doesn’t do “anything” until…
Re: Async Rust never left the MVP state
#179Earlier quoted context omitted.
Threads are neither better or worse than async+callbacks. They are different. There are problems which map nicely to threads and there are problems which are much nicer to express with async.
Such as? The entire premise of async is that callbacks were a mistake because they broke sequential reasoning and control. Every explanation of the feature starts with managing callback hell.
Re: Async Rust never left the MVP state
#180Earlier quoted context omitted.
Awaiting allows you to efficiently yield the thread to other tasks instead of blocking it. That's one of its biggest advantages.
When you block the OS does the same thing - yields to other threads.
The computational cost of context-switching threads at yield points is often many times higher than the actual workload executed between yield points. To address this you either need fewer yield points, which reduces concurrency, or you need to greatly reduce the cost of yielding. An async architecture reduces the cost of yielding by multiple orders of magnitude relative to threads.