我正在阅读go包“runtime”,看看我可以在其他(func GOMAXPROCS(n int))中设置可用于运行程序的CPU单元数。我可以强制goroutine在我选择的特定CPU上运行吗?
我正在阅读go包“runtime”,看看我可以在其他(func GOMAXPROCS(n int))中设置可用于运行程序的CPU单元数。我可以强制goroutine在我选择的特定CPU上运行吗?
在现代Go中,我不会将goroutine锁定到线程以提高效率。去1.5 添加了goroutine调度亲和性,以最小化goroutines在OS线程之间切换的频率。并且必须权衡CPU之间剩余迁移的任何成本与用户模式调度程序的好处,从而避免上下文切换到内核模式。最后,当转换成本是一个真正的问题时,有时候更好的关注点是改变你的程序逻辑,因此它需要减少切换,比如通过批量工作而不是单个工作项。
但即使考虑到所有这些,有时你只需要锁定一个goroutine,就像C API需要它一样,我会假设下面就是这种情况。
如果整个程序运行 GOMAXPROCS=1
, 然后 通过从schedutils包调用taskset实用程序来设置CPU关联性相对简单。
我曾经以为你运气不好 GOMAXPROCS > 1
因为那时候 goroutines在运行时在OS线程之间迁移。事实上,James Henstridge指出你可以使用 runtime.LockOSThread()
保持你的goroutine不迁移。但是,一旦你锁定了goroutine,我不知道任何Go stdlib函数来设置当前线程的CPU亲和力。您可以使用cgo并致电 pthread_setaffinity_np
,显然 Go在cgo模式下使用pthreads。由于我们讨论的是系统调用,因此操作系统的细节会有所不同。
(如果你的整个程序都是纯粹的Go(没有C链接),它可能会调用 sched_setaffinity
零 pid
参数通过 syscall
模块。但那会很棘手。)
取决于您的工作负载,但有时每个CPU启动一个go进程是有益的,将gomaxprocs设置为1并使用taskset将进程固定到CPU。以下是来自awesome fasthttp库的关于该主题的摘录:
资源: https://github.com/valyala/fasthttp#performance-optimization-tips-for-multi-core-systems