I've found in my own use of rust I want async/nonblocking for two things. 1. Be able to timeout a read of a socket 2. Be able to select over multiple sockets, and read whichever is ready first Usually a combination of both. epoll/io_uring(I guess? I only ever did research on epoll) seem like the solution being handed to me on a silver platter, however my understanding is if you want to use either of those you're mean…
Monoio – A thread-per-core Rust async runtime with io_uring
41–50 of 84 posts
Re: Monoio – A thread-per-core Rust async runtime with io_uring
#42Earlier quoted context omitted.
Ironically, it is not true that "async" (stackless) event loop systems don't store unnecessary processor state to memory. Those systems store the entire processing state in future object memory. It is the same state that threaded systems store. Stackful context switching systems (which includes some kinds of efficient threads - I would count Linux kernel internal threads among these) store that same state in the stac…
> It is the same state that threaded systems store. Nope. Synchronous task switching systems additionally have to store CPU register state. In the cooperative case you need to store the caller-saved registers, in the pre-emptive case you need to store all the registers. Async systems simply don’t have to do that extra work. > But some async, stackless systems do a bunch of extra work unwinding and restoring entire ca…
You only need to save caller saved registers fs your context switching routine uses the conventional ABI, but that's not a requirement.
Re: Monoio – A thread-per-core Rust async runtime with io_uring
#43Earlier quoted context omitted.
"Async runtimes" is a thing that only makes sense for interpreted languages and their limitations. This thing is pure cargo cult and shows that Rust mostly appeals to newbies who don't know what they are doing.
Yes, io_uring, a linux subsystem, is clearly just a cargo cult feature for people who don't know what they're doing.
Re: Monoio – A thread-per-core Rust async runtime with io_uring
#44Earlier quoted context omitted.
Up to 2.44x faster for network zerocopy send: https://lore.kernel.org/io-uring/cover.1638282789.git.asml.s... Up to 1.6x faster than epoll: https://twitter.com/axboe/status/1362271500489793539 io_uring 11% faster for non-polled IO: https://twitter.com/axboe/status/1465358880502861829/photo/1 And it's not like io_uring is complete. With every kernel release the gap over epoll gets bigger.
I was unable to replicate these results, and neither can other people. I'll look into it again though and see. https://github.com/axboe/liburing/issues/189 edit: I'm not sure why I'm unable to reply to the comment below but I don't think anyone is being unnecessarily combative. I linked it twice because it is relevant to both replies to my comment. There is useful information in that thread if you read it end to end.…
io_uring should be faster by design but it currently doesn’t seem to be. Maybe disk io is a different story.
Re: Monoio – A thread-per-core Rust async runtime with io_uring
#45Earlier quoted context omitted.
> for later or for never :P why not prove like... "this is the best. all other platforms/circumstances/situations are subpar" if the performance differences are enough, i can picture people making excuses to avoid all of those other platforms (or just never using this... more likely)
Agreed. I wouldn't care if Rust dropped Windows/ OSX support entirely. Totally niche platforms.
Re: Monoio – A thread-per-core Rust async runtime with io_uring
#46Re: Monoio – A thread-per-core Rust async runtime with io_uring
#47Plus, Tokio is unique in that it's one of the very few runtimes in existence that's work-stealing (meaning the task can move off its original thread). Most other runtimes in other languages do not have that requirement, meaning you can use traditional Cell/RefCell/Rc instead of their slower, atomic variants.
Right now, the best you can do is write a thread pool that spawns a Tokio LocalSet to run !Send futures. In fact, this is what Actin-web does to achieve its crazy performance. Web requests finish so quickly you rarely need work-stealing to achieve good performance, and often the cost of atomics/stealing is greater than the performance gain.
Re: Monoio – A thread-per-core Rust async runtime with io_uring
#48Have any other Rust async runtimes use io_uring/gotten at all good yet? Best of the best modern systems programmers gotta get good sometime. Not sure if it's happening yet. Ok here's one point of call: https://github.com/tokio-rs/tokio-uring
yes, check out `actix-rt`
Re: Monoio – A thread-per-core Rust async runtime with io_uring
#49That's also the most exciting thing about io_uring for me: how it enables a simple, single-threaded and yet highly performant thread-per-core control plane, outsourcing to the kernel thread pool for the async I/O data plane, instead of outsourcing to a user space thread pool as in the past. It's much more efficient and at the same time, much easier to reason about. There's no longer the need for multithreading to leak into the control plane.
My experience with io_uring has been mostly working on TigerBeetleDB [1], a new distributed database that can process a million financial transactions a second, and I find it's a whole new way of thinking... that you can now just submit I/O directly from the control plane without blocking and without the cost of a context switch. It really changes the kinds of designs you can achieve, especially in the storage space (e.g. things like LSM-tree compactions can become much more parallel and incremental, while also becoming much simpler, i.e. no longer any need to think of memory barriers). Fantastic also to now have a unified API for networking/storage.
So much good stuff in io_uring. Exciting times.
Re: Monoio – A thread-per-core Rust async runtime with io_uring
#50It's exciting to see another thread-per-core async runtime for Rust. It's truly understated how difficult the Send + Sync requirements in Tokio are for writing regular code. It's typically rare for async tasks in Tokio to be used across two threads simultaneously, but now all of your data must be Send+Sync. Plus, Tokio is unique in that it's one of the very few runtimes in existence that's work-stealing (meaning the…
If we didn't have the Send + Sync requirements, and multiple async functions are running concurrently on the same thread, and multiple of them locked the same RefCell, might that cause a panic?