Absolutely not. That's not how overcommit works. It create one, single, empty zero page and maps it over and over again. And even page structures requires to do that are also reused.
Ultimately if you are allocating 8GB of stacks (8MB each) but only using 4KB from each stack then you are losing about 50MB of memory.
Because then even if that memory isn't being used it has the same issue right?
No, no, no. Absolutely not. TSAN allocates 64TiB of address space (that's terabytes, not gigabytes). It it worked like you expect that noone would have been able to use it.
If you allocate 64TiB in small chunks and not as one big piece, then overhead would be higher, but no, it wouldn't be even remotely problematic till you would actually use that memory (and if you actually use it then async
would use it, too).
Also, I know async_io
calls read() before checking for readiness (on a non-blocking source), so wouldn't that have the same issue?
It might. But since it's part of your program and not part of OS kernel it can be easily fixed if problem would become real.
In practice, our computers are huge and powerful, so whatever you do it will probably work almost all of the time. Until, I don't know, several million customers want to access your website in a space of a few minutes.
Yeah, but if you have several million customers then usually you can afford more than one server.
So mostly it doesn't matter. But I think it's natural to use Async for any kind of server IO. There are crates like hyper and axum that make it easy, almost trivial.
Async matters a lot. But on the opposite side of spectrum. Not when you have lots of threads, but when you have two, four or eight. Because making sure you are distributing work nicely between two or four or eight threads (that's what typical customer CPUs have) and using all the resources you have⦠it's quite challenging task.
But if you split your program into lots and lots of small tasks which can be executed in parallel⦠you may get very nice speedup.
Think rustc
which is so slow everyone complains. With async
used judiciously it would have been able to use all the cores in your CPU.
Of course there are other, more pressing issues with rustc
and one or two async
functions wouldn't help, you need, basically, your whole program composed just from them. But that is much more important than threads overhead.
Which makes async
, surprisingly enough, extremely important for client programs, not server programs. Servers always had an āembarrassingly parallelā option: just run request from one customer on one thread and bam: all your cores are useful (or if they are not useful because you have too few customers then you have completely different problem). Client doesn't have such an option. It needs async
.
And yes, on opposite end of spectrum you may achieve something which requires millions of threads without async
, but these things are very rare.