众所周知,从 Go 1.0 到 Go 1.1,Go 的调度器最重要的改进就是在 GM 中添加了 P 来制作 GPM。我们可以在那里查看原始设计文档 Scalable Go Scheduler Design Doc
我很困惑为什么我们添加P来存储本地runq和mcache,而不是简单地将这些东西放在M中。俗话说“如果没有必要,就不会添加实质性”。
很明显,前者添加了一个实体,而后者没有。
为什么我们选择前者?
最佳答案
我很确定“如果没有必要,就不会添加实质性”不是一句俗语;但是我认为它是奥卡姆 Razor 的变体:不要不必要地增加实体。然而,在进程调度方面,'P'(处理器)并不是多余的概念 - 如果您缺乏与运行进程的底层硬件相对应的任何概念(除了最大处理器数量和空闲数量),那么您的调度是其实太抽象了。我不是 Go 调度器的专家,在与它相关的论文中发现了几个问题元素,但改进的核心似乎与“工作窃取”的实现有关,即空闲的 Ps 试图窃取等待的 Gs来自其他 Ps。这是有效的,因为 P 知道它何时变为空闲,而 M 本身不知道空闲硬件。
关于go - 为什么我们在 Go 调度器的设计中添加 P 而不是简单地更改 M?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60481941/