Thread spawning is fast but footprints are still pretty large. You'll likely max out around 10k threads with defaults, and maybe tweak it to 100k with small stack sizes.
Last time this came up, it was found that you can get per thread overhead down to 10KB with musl and Linux, and even smaller with upcoming Linux kernel work. That allows for quite a few more than 100,000 threads for typical server RAM configurations.
FWIW, there was an async vs. threads debate at Google that was "resolved" with one very important application running tens of thousands of threads per machine on hundreds of thousands of cores. Some people thought async would be a wiser architecture, but it was made to work (albeit with significant and literally full-stack engineering effort).
The problem of threads vs async in C seems pretty well studied, but a more interesting question is what we're talking about here: concurrency models in higher level languages: async/await in JavaScript vs. threads in JavaScript. Or let's say Python, because it actually has threads.
I feel like that tradeoff has been less well studied. Interpreters probably use a lot more stack space than native programs, but I wonder if anyone has quantified it.
And on the other hand, the downside of async is less pronounced than in C -- the whole point is to avoid "stack ripping" and explicit state machines.
And I have to echo the recent post here about the complexity of the async/await mechanisms in Python, although honestly I'm not that well-versed in the model.
Green threads usually take something on the order of 1kB per thread. That's an order of magnitude more threads per machine, but this is not even the greatest benefit.
Green threads shine because they take ~1kB without tweaking. That means you just pack your software, send elsewhere, and you get those millions of threads per server, instead of losing hours on customer support, and have it revert to 10k threads at random because of bad sysadmins.
Anyway, "thread" is not really a concurrency oriented concept. It mixes so much of parallelism that it's expected that it has some downsides compared o purely concurrent concepts.
It's still an order of magnitude more than many green threads implementations.
musl is interesting though. I've never seen it pitched as a solution for normal machines. I've always seen it in the context of small embedded systems.
Comments
Thread spawning is fast but footprints are still pretty large. You'll likely max out around 10k threads with defaults, and maybe tweak it to 100k with small stack sizes.
Last time this came up, it was found that you can get per thread overhead down to 10KB with musl and Linux, and even smaller with upcoming Linux kernel work. That allows for quite a few more than 100,000 threads for typical server RAM configurations.
FWIW, there was an async vs. threads debate at Google that was "resolved" with one very important application running tens of thousands of threads per machine on hundreds of thousands of cores. Some people thought async would be a wiser architecture, but it was made to work (albeit with significant and literally full-stack engineering effort).
The problem of threads vs async in C seems pretty well studied, but a more interesting question is what we're talking about here: concurrency models in higher level languages: async/await in JavaScript vs. threads in JavaScript. Or let's say Python, because it actually has threads.
I feel like that tradeoff has been less well studied. Interpreters probably use a lot more stack space than native programs, but I wonder if anyone has quantified it.
And on the other hand, the downside of async is less pronounced than in C -- the whole point is to avoid "stack ripping" and explicit state machines.
And I have to echo the recent post here about the complexity of the async/await mechanisms in Python, although honestly I'm not that well-versed in the model.
https://news.ycombinator.com/item?id=12829759
(Interesting that the top comment there is kind of echoing our issue with M:N threading -- the inner platform effect.)
Green threads usually take something on the order of 1kB per thread. That's an order of magnitude more threads per machine, but this is not even the greatest benefit.
Green threads shine because they take ~1kB without tweaking. That means you just pack your software, send elsewhere, and you get those millions of threads per server, instead of losing hours on customer support, and have it revert to 10k threads at random because of bad sysadmins.
Anyway, "thread" is not really a concurrency oriented concept. It mixes so much of parallelism that it's expected that it has some downsides compared o purely concurrent concepts.
It's still an order of magnitude more than many green threads implementations.
musl is interesting though. I've never seen it pitched as a solution for normal machines. I've always seen it in the context of small embedded systems.
Yeah, but that is a very specific OS stack, which cannot be generalized to language runtimes running on top of general purpose OSes.
Now when targeting bare metal deployments like unikernels, it is a different story in how to approach it.