News for hackers. Stuff that matters.
Re:Memory efficiency of parallel IO operations in Python by lmm on Tuesday March 13, 2018 @08:15AM (#16575495)
If you flip the perspective and look at it from an async-first point of view, then OS-level processes are just a task implementation where every operation is a (potential) yield point and the state passed between them is the C stack. There are two flaws to this, one arguable, one less so:

1. Yield points are implicit rather than explicit, so their interaction with other effects is unpredictable. https://glyph.twistedmatrix.com/2014/02/unyielding.html has a description of the problem; more generally think about the reputation that thread safety bugs have. (There are those who argue that the advantages of implicit pervasive yielding outweigh the disadvantages).

2. At every yield the processor has to swap out the full C stack (usually 4K or 8K). This is a slow operation ("context switch") and inefficient when often the only information that actually needed to be passed from one task to the next was a single integer (e.g. a socket ID, user ID, SQL query ID, etc.) or something similarly small. Whereas with userspace scheduling, a task switch only has to pass the actual task state that's needed for the task in question.

Re:Memory efficiency of parallel IO operations in Python by TickleSteve on Tuesday March 13, 2018 @08:39AM (#16575614)
Small point, but stack-pointers are swapped... not the full stack. The way you've worded it makes it seem like the whole stack is copied which of course is not the case.
Re:Memory efficiency of parallel IO operations in Python by jacobush on Tuesday March 13, 2018 @11:32AM (#16576932)
True and in a machine with 0 cache, it's 100% true. Though, in real world with caches, it a little muddier. Yes, the stack pointer is switched. Depending on how much is referenced off that stack pointer, though, much of the stack may be in fact switched - in the cache.
Re:Memory efficiency of parallel IO operations in Python by jstimpfle on Tuesday March 13, 2018 @09:45AM (#16576007)
Right. And I think a typical stack size is ballpark 8MB, not 8KB, these days.
Re:Memory efficiency of parallel IO operations in Python by scottlamb on Tuesday March 13, 2018 @01:12PM (#16577700)
It varies. 8MiB is believable. That's 8MiB (plus a guard page) of address space. Typically it's divided into 4KiB ("small") pages which are only backed with real RAM once accessed. So maybe only 4KiB of real RAM, depending on what your program is doing...plus whatever bookkeeping the kernel needs, which I think can be as much as 128KiB on Linux, unfortunately. (At least something makes it use that much for me at work, although it might be related to something special I'm doing.)

It's also possible (but not common) to release accessed-but-no-longer-needed pages. Doing this when returning to a thread pool avoids situations where one occasional deep call chain causes all the threads in the pool to eventually become huge.

Re:Memory efficiency of parallel IO operations in Python by Cyph0n on Tuesday March 13, 2018 @11:31AM (#16576922)
I was working with pthreads recently and the default thread stack size is 8M.
Re:Memory efficiency of parallel IO operations in Python by belovedeagle on Tuesday March 13, 2018 @11:29AM (#16576904)
But it is: bringing the new stack into the cache, and eventually flushing the dirty one back to memory, is essentially the same as copying it.
Re:Memory efficiency of parallel IO operations in Python by simias on Tuesday March 13, 2018 @08:51AM (#16575680)
Thread swapping has a non-negligible cost but I'm not sure what you mean by swapping the stack. Aren't they just swapping stack pointers? That's how I'd naively implement it.

You still have to bank a whole bunch of registers and there might be detrimental side effects but I can't imagine why the stack would get in the way. Process swapping is obviously much worse since you change the process ID and the virtual memory mapping but even then I don't see why you'd ever copy the stack.

Re:Memory efficiency of parallel IO operations in Python by lmm on Tuesday March 13, 2018 @08:54AM (#16575701)
Yes, you're right. The size of the stack is relevant to how much memory each switched-out task takes up, but not directly to how costly the switching process is.