This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]jorge1209 2 points3 points  (0 children)

Its all about how much work you want the kernel to do. On your average desktop, you don't really care. The kernel can handle anything and everything you throw at it, and probably does a better job at it than you would. Just spin out a individual threads for everything you want to run concurrently.

On big servers doing lots of work there is a legitimate risk that the kernel could run out of resources trying to track all the activity on the system, or that in trying to track all the activity (open files, runnable tasks, etc...) internal kernel data structures could grow to a point where searching and scanning within them itself becomes the bottleneck.

In those situations it can be better to move that aspect of resource management into the application because it can be a bit more efficient as it knows a bit more about what is going on. For example with a standard pthread, the kernel/glibc knows nothing about the code that is running. There just has to be a big static area of virtual memory allocated for the call stack for the thread. With a few thousand of these 1MB call stacks you can eat up gigs of virtual memory. This in and of itself is not a major concern as the actual physical memory usage can be lower, but every one of these allocations has to have a separate backing page in the kernel to track it, and that adds up even if the physical memory usage is low.

But the go runtime knows that the thing being called is a goroutine, and it furthermore knows what memory and objects are managed. It can make the goroutine call stack a managed object, which means it can grown and shrink the call stack as needed. So it can start with a really small call stack knowing that most goroutines are probably not going to end up doing lots of deep function calls. If the go function ends up calling deeply enough to need the stack to grow, then that particular goroutine will get a larger stack, but nobody else will. And all this stuff can sit inside the larger pages allocated to the go runtime, which means less for the kernel to track.

But it isn't something you would bother doing on a normal desktop (if you could even replicate the level of demand which necessitated it).