[我们知道,从Go 1.0到Go 1.1,Go的调度程序最重要的改进是在GM上添加了P,以形成GPM。我们可以在其中看到原始设计文档Scalable Go Scheduler Design Doc
我很困惑,为什么我们添加P来存储本地runq和mcache,而不是简单地将这些内容放入M。俗话说,“如果没有必要,就不会添加实质性内容”。显然,前者添加了一个实体,而后者却没有。
为什么我们选择前者?
我很确定“如果没有必要,将不会添加实质性内容”;但是,我认为这是Occam剃刀的一种变体:不要不必要地增加实体。然而,关于进程调度,“ P”(处理器)并不是多余的概念-如果您缺少与运行进程的基础硬件相对应的任何概念(除了最大处理器数量和可用数量之外),那么您的调度是其实太抽象了。我不是Go调度程序的专家,并且链接的文档中确定了一些有问题的元素,但是改进的核心似乎与“工作窃取”的实现有关,即闲置的P尝试窃取等待的Gs从其他PS。这是有效的,因为P知道它何时变为空闲,而M本身不知道空闲的硬件。