I’ve never understood the “async I/O is too complicated, why can’t we just use goroutines?” criticism of Rust. You can! They’re called threads, and they work great.
14
25
150
This Tweet was deleted by the Tweet author. Learn more
This is the result of an argument between me and a friend over scalability of OS threads.
- You can't spawn 10ks threads in OS.
- Yes you can!
- Oh really? Just try that!
- Here you go:
You can spawn far more than thousands of OS threads. The practical limit on Linux for threads with guard pages is based on the arbitrary max_map_count configuration option, and that's due to the approach to detecting stack overflow rather than the choice of 1:1 vs M:N scheduling.
Raise that arbitrary limit (there's no memory or performance cost) and the limit on the number of threads with guard pages goes up with it. The next practical limit is address space size due to stack size, but again that's a different design decision and not tied to 1:1 vs. M:N.
There's enough address space on x86_64 and arm64 to spawn literally millions of threads with an 8MiB stack mapping anyway. It doesn't depend on overcommit either, since you can implement stacks per the main thread stack by reserving the space and mapping it in as it's touched.
Well, yeah, but you still allocate in place granularity, right?. RAM is the most expensive real estate you have in your server.
The less you use it, the cheaper your are. This is especially true fur long lived connections, where a busy server is expected to keep a few millions..
Go stacks currently start at 2048 bytes but there's substantial memory overhead elsewhere to implement the model, so that's a bit misleading. The difference is not what people make it out to be. I recommend trying it out and measuring actual memory usage for a simple TCP server.