Live data from Hacker News

Monoio – A thread-per-core Rust async runtime with io_uring

github.com

51–60 of 84 posts

Re: Monoio – A thread-per-core Rust async runtime with io_uring

#51

It'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…

> the best you can do is write a thread pool that spawns a Tokio LocalSet to run !Send futures

Can you go into this a bit more or provide a code reference? I'm new to writing async Rust code and am interested in this idea.

Re: Monoio – A thread-per-core Rust async runtime with io_uring

#52
post #49

With context switches becoming more and more expensive relative to faster and faster I/O devices, almost the same order of magnitude, I believe that thread-per-core is where things are heading, because the alternative of not doing thread-per-core might literally be halving your throughput. That's also the most exciting thing about io_uring for me: how it enables a simple, single-threaded and yet highly performant thr…

Totally. And these thread per core apps can talk directly to virtio or NVMe passed into the kvm guest, you can get the best of having a unix host but have applications that run directly under KVM w/o sacrificing a rich control plane. And control plane reliability doesn't impact the data plane. Wonderful times!

Re: Monoio – A thread-per-core Rust async runtime with io_uring

#54

I have a stupid question, why isn't an async runtime a language feature of rust? we don't seem to see so many async runtimes in other languages? They seem to have a default way to run async tasks?

an async runtime inherently requires knowledge of the underlying system which Rust remains agnostic to. Rust can be written to target bare-metal (where no OS exists) to WASM and everything in between. If a runtime was added to the language itself you would inherently limit the flexibility of the platforms by which it could target.

Re: Monoio – A thread-per-core Rust async runtime with io_uring

#55
post #2

Have 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

> Have any other Rust async runtimes use io_uring/gotten at all good yet? yes, check out `actix-rt` https://github.com/actix/actix-net

actix-rt is a wrapper around tokio's single threaded runtime, and (optionally) tokio-uring.

Re: Monoio – A thread-per-core Rust async runtime with io_uring

#56

I have a stupid question, why isn't an async runtime a language feature of rust? we don't seem to see so many async runtimes in other languages? They seem to have a default way to run async tasks?

It sort of goes against Rust’s philosophy to bake anything like that into the language.

Where they screwed up was not providing the machinery to make libraries agnostic of the runtime an end user wants to use in their program, so libraries either depend on a specific runtime explicitly or use features to allow users to switch runtimes at compile time. This causes a lot of headaches for library maintainers and end users both.

There’s a lot of interest in adding said machinery (through collections of traits in std) to enable libraries to be generic over different runtimes, but a solution is still some ways off.

Re: Monoio – A thread-per-core Rust async runtime with io_uring

#57

It'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…

> 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.

https://docs.rs/tokio/1.14.0/tokio/task/fn.spawn_local.html

> Plus, 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.

Most other languages don't have any concept of Send/Sync, or non-atomic Cell/RefCell/Rc. Rather than the compiler stopping you you only find out about the issue when you hit it, and if you're lucky you can skate by a long long while (or alternatively the language has no way to sync and everything's send).

Work-stealing runtimes may be more common than you think because of that: Erlang's BEAM, Go's scheduler(s), Java's fork/join, .net's TPL, many most if not all OpenMP implementations, Apple's GCD, ... implement work-stealing in various measures.

Also... thread-per-core makes work-stealing even more necessary because the OS can't perform the balancing? The only ways to avoid work-stealing eventually becoming necessary (for a general-purpose scheduler) is either to have a completely single-threaded scheduler, or to not have an application-level scheduler at all and use OS threads.

Re: Monoio – A thread-per-core Rust async runtime with io_uring

#58

Earlier quoted context omitted.

Agreed. I wouldn't care if Rust dropped Windows/ OSX support entirely. Totally niche platforms.

I think you're being sarcastic, but I'm not totally sure.

I'm honestly not. Desktop platforms like Windows are incredibly niche. How much rust software actually runs on those? Some, of course. But probably an incredible minority.

Supporting them is smart because people expect it, and not supporting it would be bad optics, but if a language legitimately only targeted Linux, and was better for it, I'd be fine with that - they target the most popular OS by far.

Re: Monoio – A thread-per-core Rust async runtime with io_uring

#59

Earlier quoted context omitted.

> 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…

A cooperative synchronous task switching (i.e. fiber based) need only save the exact same information as an async based one (i.e. stackless coroutines): at a minimum a context pointer and an instruction pointer. Plus any live registers (which might be none). You only need to save caller saved registers fs your context switching routine uses the conventional ABI, but that's not a requirement.

> You only need to save caller saved registers fs your context switching routine uses the conventional ABI, but that's not a requirement.

If you request a task switch from C or any high level language that has the concept of caller-saved registers and the compiler has no knowledge of your task switching system (vast majority of cases) you will be forced to pay an extra cost. Is there a practical system in common use that is able to elide register-saves that you’re referring to? Or is your point essentially that you don’t have save caller-saved/live registers in the theoretical case that you have no caller-saved/live registers?

Re: Monoio – A thread-per-core Rust async runtime with io_uring

#60

It'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…

I've been thinking about how one could get around the Send + Sync requirements, it's a fascinating conundrum, from a language design standpoint. 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?

> 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?

Hopefully.

Post reply on HN