Number of threads used by Go runtime

fumoboy007 picture fumoboy007 · Aug 31, 2016 · Viewed 14.5k times · Source

How many threads can the Go runtime (scheduler, garbage collector, etc.) use? For example, if GOMAXPROCS is 10, how many of those kernel threads would be used by the runtime?

Edit:

I was reading the rationale for changing GOMAXPROCS to runtime.NumCPU() in Go 1.5. There was a sentence that claimed that “the performance of single-goroutine programs can improve by raising GOMAXPROCS due to parallelism of the runtime, especially the garbage collector.”

My real question is: If I have a single-goroutine program running in a Docker container that has a CPU quota, what is the minimum number of logical processors that I need in order to have maximum performance?

Answer

icza picture icza · Aug 31, 2016

There is no direct correlation. Threads used by your app may be less than, equal to or more than 10.

Quoting from the package doc of runtime:

The GOMAXPROCS variable limits the number of operating system threads that can execute user-level Go code simultaneously. There is no limit to the number of threads that can be blocked in system calls on behalf of Go code; those do not count against the GOMAXPROCS limit. This package's GOMAXPROCS function queries and changes the limit.

So if your application does not start any new goroutines, threads count will be less than 10.

If your app starts many goroutines (>10) where none is blocking (e.g. in system calls), 10 operating system threads will execute your goroutines simultaneously.

If your app starts many goroutines where many (>10) are blocked in system calls, more than 10 OS threads will be spawned (but only at most 10 will be executing user-level Go code).

See this question for an example and details: Why does it not create many threads when many goroutines are blocked in writing file in golang?

Edit (in response to your edit):

I believe the default value of GOMAXPROCS is the number of logical CPUs for a reason: because in general that provides the highest performance. You may leave it at that. In general if you only have 1 goroutine and you're sure your code doesn't spawn more, GOMAXPROCS=1 is sufficient, but you should test and don't take any word for it.