Async-await on stable Rust
321–330 of 392 posts
Re: Async-await on stable Rust
#322Earlier quoted context omitted.
The solution suggested by that article is to use M:N threading, which was tried in Rust and turned out to be slower than plain old 1:1 threading. If you don't want to deal with async functions, then you can use threads! That's what they're there for. On Linux they're quite fast. Async is for when you need more performance than what 1:1 or M:N threading can provide.
How hard was it tried? I imagine there's a reason that languages like Go adopted M:N threading... obviously part of the reason is that it's way more scaleable, but userspace threading is also supposed to be faster, as context switches don't need to switch to kernel space... were the problems tight loops (which AFAIK is also the problem in Go)? or maybe it's just so much easier / more efficient if you also have GC...
These languages (Erlang, Haskell, Go, ...) have no ambition to be useful for system programming; they're not intended as a replacement for C/C++ in that domain, unlike Rust.
Re: Async-await on stable Rust
#323This is a big improvement, however this is still explicit/userland asynchronous programming: If anything down the callstack is synchronous, it blocks everything. This requires every components of a program, including every dependency, to be specifically designed for this kind of concurency. Async I/O gives awesome performance, but further abstractions would make it easier and less risky to use. Designing everything a…
> Async I/O gives awesome performance No, it doesn't really. 'Async' is a strictly Python problem, due to the insanity of the GIL. Predictably, the Python solution to it is also insane. Why you have to turn a sane language like Rust into an insane one by cargo-culting a solution to a non-problem is a mystery to me. Oh well, good thing at least C++ hasn't dropped the ball.
- Asynchronous programming is completely orthogonal to Python
- If you don't need it, don't use it. Rust without asynchronous functions still looks and works like before
- By the way: welcome to C++20's coroutines
Re: Async-await on stable Rust
#324I’ve been playing with async await in a polar opposite vertical than its typical use case (high tps web backends) and believe this was the missing piece to further unlock great ergonomic and productivity gains for system development: embedded no_std. Async/await lets you write non-blocking, single-threaded but highly interweaved firmware/apps in allocation-free, single-threaded environments (bare-metal programming wi…
Yeah, that's a super interesting idea that I'm also toying with in my head. One issue however is the "allocation-free" part. Sooner or later you typically hit a situation where you need to box a Future - either because you want to spawn it dynamically or need dynamic dispatch and type erasure. At that point of time you will need an allocator. I'm still wondering if lots of the problems can be solved with an "allocate…
Re: Async-await on stable Rust
#325Earlier quoted context omitted.
Just to clarify for those following along, Rust async code does not use green threads and doesn't require a stack per task.
I'm missing some of the technical details here, but from a quick glance of the article it seems like Rust's futures are lazy . I.e. a stack would only be allocated when the future is actually awaited. But in order to execute the relevant code, a call stack per not-finished future is still needed, or am I missing something?
Re: Async-await on stable Rust
#326Earlier quoted context omitted.
I also think async (the paradigm) is kind of weird in rust world. I agree with https://journal.stuffwithstuff.com/2015/02/01/what-color-is-... .
All 5 of his points seem to be 2015 Javascript only. Some of them don't even apply to modern Javascript; I don't see any that apply to rust.
Re: Async-await on stable Rust
#327Earlier quoted context omitted.
No, its conclusion is that fibers with certain properties in C/C++ are slower -- and particularly hard to implement correctly -- than stackless coroutines in C/C++ . That's because of the particular characteristics of those languages. In fact, you'll note that the only negative thing he says about Go is that it incurs an overhead when interacting with non-Go code.
And that overhead is a deal-breaker in Rust.
Re: Async-await on stable Rust
#328Earlier quoted context omitted.
What you tried wasn't "this", though. It was one particular implementation of lightweight threading that has to cope with Rust's peculiarities, special requirements and compilation targets. There is absolutely nothing essential about lightweight threads that prevents them from emitting essentially the same code as the stackless-coroutine approach. It's just that in Rust it might be very hard or even not worth it, giv…
I don't understand what your objection is. It's a given that what I wrote applies to Rust. This is a thread about Rust. I didn't say that M:N threading is always slower than 1:1. Besides, fibers don't emit essentially the same code as async code. One has a stack, and the other doesn't. That's a significant difference.
> One has a stack, and the other doesn't. That's a significant difference.
They both have some memory area to which they write state. Calling it "a stack" refers to the abstraction in the programmer's mind, not to how the memory is actually written/read. It is true that in order to support recursion, a thread might need to dynamically allocate memory, but so would async/await, except it'll make it more explicit.
Re: Async-await on stable Rust
#329Earlier quoted context omitted.
I'm missing some of the technical details here, but from a quick glance of the article it seems like Rust's futures are lazy . I.e. a stack would only be allocated when the future is actually awaited. But in order to execute the relevant code, a call stack per not-finished future is still needed, or am I missing something?
because of syntactical restrictions of how await work, at most you need to allocate a single function frame, never a full stack, and often it doesn't even need to be allocated separately and can live in the stack of the underlying OS thread.
Re: Async-await on stable Rust
#330Earlier quoted context omitted.
I'm missing some of the technical details here, but from a quick glance of the article it seems like Rust's futures are lazy . I.e. a stack would only be allocated when the future is actually awaited. But in order to execute the relevant code, a call stack per not-finished future is still needed, or am I missing something?
Afaik Rust's futures compile to a state machine, which is basically just a struct that contains the current state flag and the variables that need to be kept across yield points. An executor owns a list of such structs/futures and executes them however it sees fit (single-threaded, multi-threaded, ...). So there is no stack per future. The number of stacks depends on how many threads the executor runs in parallel.
you mean like... a stack frame?