随笔 - 809  文章 - 0 评论 - 144 阅读 - 770万

在 Go 语言的 GMP 模型中,调度器负责将 goroutine 分配到不同的 P(Processor)上执行。当本地的 goroutine 队列(称为 LRQ,Local Run Queue)为空时,P 会尝试从全局的 goroutine 队列(称为 GQ,Global Run Queue)中获取 goroutine 来执行。为了平衡负载和效率,Go 调度器使用了一个公式来决定从全局队列中一次取多少个 goroutine 到本地队列。

这个公式是:

$$ n = \min\left(\frac{\text{len(GQ)}}{\text{GOMAXPROCS}} + 1, \frac{\text{len(GQ)}}{2}\right) $$

下面是对这个公式的详细解释:

  1. GOMAXPROCS:这是 Go 程序运行时的一个环境变量或参数,它指定了程序可以同时使用的最大 CPU 核心数(即 P 的数量)。这个值可以通过 runtime.GOMAXPROCS(n int) 函数来设置,如果不设置,默认值是机器的 CPU 核心数。

  2. len(GQ):这是全局 goroutine 队列中当前待执行的 goroutine 的数量。

  3. $\frac{\text{len(GQ)}}{\text{GOMAXPROCS}} + 1$:这部分的意思是,将全局队列中的 goroutine 均匀地分配给每个 P,然后再加 1。加 1 的目的是为了确保即使全局队列中的 goroutine 数量很少,每个 P 也能至少获取到一个 goroutine,从而避免饥饿问题。

  4. $\frac{\text{len(GQ)}}{2}$:这部分是一个限制,意味着一次从一个 P 试图从全局队列中获取 goroutine 的数量不会超过全局队列中 goroutine 总数的一半。这是为了防止一个 P 一次性取走太多 goroutine,导致其他 P 长时间无法获取到工作,从而保持系统的负载均衡。

  5. $\min(...)$:最终取这两个计算结果中的较小值,作为一次从全局队列中取走的 goroutine 的数量。这样做既考虑了负载均衡,又考虑了效率,确保每个 P 都能有效地获取到工作,同时避免单个 P 负担过重。

综上所述,这个公式旨在平衡 Go 程序中 goroutine 的分配,确保所有 P 都能有效地获取到工作,同时避免任何 P 过载或饥饿。通过动态调整从全局队列中获取 goroutine 的数量,Go 调度器能够有效地利用多核 CPU 的性能,提高程序的执行效率。

posted on   del88  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示