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?
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?
In the Go programming language there is a limit of 10000 threads (pthreads not goroutines). Once this limit is hit an error is issue and the program dies with a fatal error.
At any time, at most only one thread is allowed to run per core. But scheduler can create more threads if required, but that rarely happens. If your program doesn't start any additional goroutines, it will naturally run in only one thread no matter how many cores you allow it to use.
With Go, it's possible to do multi-threaded concurrency and parallelization with goroutines and goroutines work in an asynchronous way hence making use of both multi-threading and asynchronous programming efficiently.
The Go runtime in the flexible environment is the software stack responsible for building and running your code. To choose the Go runtime in the flexible environment, add two lines to your app. yaml file. Runtimes in the flexible environment are built using Docker.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With