goruntime

Is it possible to force a Go routine to be run on a specific CPU?


I am reading about the go package "runtime" and see that I can among other (func GOMAXPROCS(n int)) set the number of CPU units that can be used to run my program.

Can I force a goroutine to be run on a specific CPU of my choice?


Solution

  • In modern Go, I wouldn't lock goroutines to threads for efficiency. Go 1.5 added goroutine scheduling affinity, to minimize how often goroutines switch between OS threads. And any cost of the remaining migrations between CPUs has to be weighed against the benefit of the user-mode scheduler avoiding context switches into kernel mode. Finally, when switching costs are a real problem, sometimes a better focus is changing your program logic so it needs to switch less, like by communicating batches of work instead of individual work items.

    But even considering all that, sometimes you simply have to lock a goroutine, like when a C API requires it, and I'll assume that's the case below.


    If the whole program runs with GOMAXPROCS=1, then it's relatively simple to set a CPU affinity by calling out to the taskset utility from the schedutils package.

    I had thought you were out of luck if GOMAXPROCS > 1 because then goroutines are migrated between OS threads at runtime. In fact, James Henstridge points out you can use runtime.LockOSThread() to keep your goroutine from migrating.

    That doesn't solve locking the OS thread to a CPU. @yerden points out in a comment that the SchedSeatffinity function in the golang.org/x/sys/unix package, using 0 as the pid, ought to lock the calling thread to its current CPU.

    In the "C API requires locking" use case, it might also work to call pthread_setaffinity_np from C code.

    I haven't tested either of those ways to lock threads to CPUs, and details will vary by OS there.