Live data from Hacker News

Goroutines Under the Hood (2020)

osmh.dev

41–50 of 55 posts

Re: Goroutines Under the Hood (2020)

#42

One thing that really goes against my intuition is that user space threads (lightweight treads, goroutines) are faster than kernel threads. Without knowing too much assembly, I would assume any modern processor would make a context switch a one instruction affair. Interrupt -> small scheduler code picks the thread to run -> LOAD THREAD instruction and the processor swaps in all the registers and the instruction point…

On Linux, 99% of the time, you want kernel threads. They can be configured to use very little stack memory. They can be configured to reduce the scheduling overhead by using NOOP scheduling which works for certain workloads. They are rock solid.

Spawning millions of unnecessary user-space threads because they are supposed to be more efficient than kernel threads is rarely the best solution to any problem imho.

Re: Goroutines Under the Hood (2020)

#43
post #24

I've fallen in love with Python's asyncio for some time now, but I know that go has coroutines integrated as a first class citizen. This article (which I have not read but just skimmed) made me search for a simple example, and I landed at "A Tour of Go - Goroutines"[0] That is one of the cleanest examples I've ever seen on this topic, and it shows just how well integrated they are in the language. [0] https://go.dev/…

Having used both in production for many years, Go’s model is waayyyy better, mostly because Python’s model results in a bunch of runtime bugs. The least of which are type error things like forgetting to await an async function—these can be caught with a type checker (although this means you need to have a type checker running in your CI and annotations for all of your dependencies). The most serious are the ones wher…

I’m not a Go programmer, doesn’t having everything async make your code riddled with race conditions? It seems like it would make ordering very hard to reason about.

Re: Goroutines Under the Hood (2020)

#44

So it's just coroutines on top of n:m scheduling, similar to what SysV offered a while ago?

SysV? Are you thinking Solaris?

There have been various implementations of M:N threads for some time now. The concept is simple, but the devil is in the details.

Re: Goroutines Under the Hood (2020)

#45

In the conclusion the author states: >"Go run-time scheduler multiplexes goroutines onto threads and when a thread blocks, the run-time moves the blocked goroutines to another runnable kernel thread to achieve the highest efficiency possible." Why would the Go run-time move the blocked goroutines to another runnable kernel thread? If it is currently blocked it won't be schedulable regardless no?

There's no reason to move the blocked task.

But any other tasks queued up behind the blocked task could be moved to another OS thread where they'll have a chance of running.

Re: Goroutines Under the Hood (2020)

#46

In the conclusion the author states: >"Go run-time scheduler multiplexes goroutines onto threads and when a thread blocks, the run-time moves the blocked goroutines to another runnable kernel thread to achieve the highest efficiency possible." Why would the Go run-time move the blocked goroutines to another runnable kernel thread? If it is currently blocked it won't be schedulable regardless no?

There's no reason to move the blocked task. But any other tasks queued up behind the blocked task could be moved to another OS thread where they'll have a chance of running.

Yeah I thought it was an odd statement to make especially as part of the conclusion.

Re: Goroutines Under the Hood (2020)

#47

Earlier quoted context omitted.

Having used both in production for many years, Go’s model is waayyyy better, mostly because Python’s model results in a bunch of runtime bugs. The least of which are type error things like forgetting to await an async function—these can be caught with a type checker (although this means you need to have a type checker running in your CI and annotations for all of your dependencies). The most serious are the ones wher…

I’m not a Go programmer, doesn’t having everything async make your code riddled with race conditions? It seems like it would make ordering very hard to reason about.

No, only mutable shared state is subject to race conditions. Mutable shared state is rare, and you can use a mutex to guarantee exclusive access to it. Note also that only the implementation is async, but the programmer interface is synchronous (in other words, the programmer doesn’t need to type “await” all over the place).

Re: Goroutines Under the Hood (2020)

#48
post #14

One thing that really goes against my intuition is that user space threads (lightweight treads, goroutines) are faster than kernel threads. Without knowing too much assembly, I would assume any modern processor would make a context switch a one instruction affair. Interrupt -> small scheduler code picks the thread to run -> LOAD THREAD instruction and the processor swaps in all the registers and the instruction point…

>I would assume any modern processor would make a context switch a one instruction affair. Has been the historic assumption, has been proven to be wrong by every possible benchmark. Consider tech empower[0] for raw stack performance , runtime level threads outperform IO threads since OS thread were designed to be mapped on physicals cores. This is very expensive and inefficient. Creating one thread for every request…

> Creating one thread for every request you have ( Apache + PHP ) will exhaust the hardware after a few thousands/qps target.

PHP installations more realistically use nginx and FastCGI. This is not one thread per request and it’s also a better design than hosting your entire server and every user request in the same process; that’s just asking for security issues.

Re: Goroutines Under the Hood (2020)

#49
post #6

Earlier quoted context omitted.

Why is spending GB on stack space a bad thing? Ultimately, in a server, you need to store state for each request. Whether that's on the stack or heap, it's still memory that necessarily has to be used.

Despite popular belief, not everything is a (web) server. I can imagine many threads to be appealing in e.g. simulations.

I definitely can’t hire anyone in this thread to work on cell phone performance. We fight for 10 KBs of memory and yes, we are still doing this in 2022.

Even on a server, you may have TBs of RAM but you don’t have that much L1 cache nor that much memory bandwidth.

Re: Goroutines Under the Hood (2020)

#50

Earlier quoted context omitted.

Despite popular belief, not everything is a (web) server. I can imagine many threads to be appealing in e.g. simulations.

I definitely can’t hire anyone in this thread to work on cell phone performance. We fight for 10 KBs of memory and yes, we are still doing this in 2022. Even on a server, you may have TBs of RAM but you don’t have that much L1 cache nor that much memory bandwidth.

Why would you need hundreds of thousands or millions of goroutines for a cell phone app/daemon?

I would expect the number (and corresponding memory usage) to therefore be low.

Post reply on HN