如何更改 Linux CPU 调度程序使用的时间片长度?

sou*_*edi 10 linux-kernel tuning

是否可以增加 Linux CPU 调度程序允许进程运行的时间片长度?我怎么能这样做?

背景知识

这个问题询问如何减少内核强制在同一 CPU 上运行的不同进程之间切换的频率。这是被描述为“抢占式多任务”的内核特性。此功能通常很好,因为它可以阻止占用 CPU 并使系统完全无响应的单个进程。然而,进程之间的切换是有代价的,因此需要权衡。

如果您有一个进程使用它可以获得的所有 CPU 时间,另一个进程与用户交互,那么更频繁地切换可以减少延迟响应。

如果您有两个进程使用了​​它们所能获得的所有 CPU 时间,那么减少切换频率可以让它们在同一时间内完成更多的工作。

动机

我根据我对如何更改 Linux 上下文切换频率这个问题的最初反应来发布此内容

我个人不想改变时间片。但是,我依稀记得这是一个带有CONFIG_HZ构建时选项的东西。所以我想知道现在的情况。CPU 调度程序时间片是否仍然基于CONFIG_HZ

此外,在实践中构建时调整非常有限。对于 Linux 发行版,如果每个 CPU 架构可以有一个内核,并允许在运行时或至少在启动时对其进行配置,则更为实用。如果调整时间片仍然相关,是否有一种新方法不会在构建时将其锁定?

sou*_*edi 10

对于大多数 RHEL7 服务器,RedHat 建议增加到sched_min_granularity_ns10 毫秒和 15 毫秒sched_wakeup_granularity_ns。(来源。从技术上讲,此链接表示 10 ?s,这将小 1000 倍。这是一个错误)。

我们可以尝试更详细地理解这个建议。

增加 sched_min_granularity_ns

在当前的 Linux 内核上,CPU 时间片由完全公平调度程序 CFS 分配给任务。CFS 可以使用一些sysctl设置进行调整。

  • kernel.sched_min_granularity_ns
  • kernel.sched_latency_ns
  • kernel.sched_wakeup_granularity_ns

您可以临时设置 sysctl 直到下次重新启动,或者在每次启动时应用的配置文件中永久设置。要了解如何应用此类设置,请查找“sysctl”或阅读此处的简短介绍。

sched_min_granularity_ns是最突出的设置。在最初的sched-design-CFS.txt 中,这被描述为唯一的“可调”设置,“将调度程序从‘桌面’(低延迟)调整到‘服务器’(良好的批处理)工作负载。”

换句话说,我们可以更改此设置以减少上下文切换的开销,从而以响应性(“延迟”)为代价提高吞吐量。

我认为这个 CFS 设置模仿了之前的构建时设置CONFIG_HZ。在 CFS 代码的第一个版本中,默认值为 1 ms,相当于“桌面”使用的 1000 Hz。CONFIG_HZ 的其他支持值为 250 Hz(默认值),“服务器”端为 100 Hz。在非常慢的 CPU 上运行 Linux 时,100 Hz 也很有用,这是首次将 CONFIG_HZ 添加为 X86 上的构建设置时给出的原因之一。

尝试将此值更改为 10 ms(即 100 Hz)并测量结果听起来很合理。请记住,sysctls 以ns 为单位。1 毫秒 = 1,000,000 纳秒。

我们可以看到这种对“服务器”的老式调优在 2011 年仍然非常重要,对于一些高负载基准测试的吞吐量:https : //events.static.linuxfound.org/slides/2011/linuxcon/lcna2011_rajan.pdf

也许还有其他一些设置

上述三个设置的默认值看起来彼此比较接近。这让我想保持简单,并将它们全部乘以相同的系数:-)。但我试图对此进行研究,似乎一些更具体的调整也可能相关,因为您正在调整吞吐量。

sched_wakeup_granularity_ns关注“唤醒先发制人”。即它控制何时被事件唤醒的任务能够立即抢占当前正在运行的进程。2011 年的幻灯片也显示了此设置的性能差异。

另请参阅IBM 2010 年参考资料中的“禁用 WAKEUP_PREEMPT” ,这表明“对于某些工作负载”,此默认功能“可能会占用 CPU 利用率的几个百分点”。

SUSE Linux 有一个文档建议将此设置为大于一半sched_latency_ns将有效禁用唤醒抢占,然后“短占空比任务将无法有效地与 CPU 猪竞争”。

SUSE 文档还建议对其他设置进行一些更详细的描述。不过,您绝对应该检查自己系统上的当前默认值。例如,我系统上的默认值似乎与 SUSE 文档所说的略有不同。

https://www.suse.com/documentation/opensuse121/book_tuning/data/sec_tuning_taskscheduler_cfs.html

如果您尝试使用这些调度变量中的任何一个,我认为您还应该意识到这三个变量都按 CPU 数量的 1+log_2 进行了缩放(相乘)。可以使用 禁用此缩放kernel.sched_tunable_scaling。我可能会遗漏一些东西,但这似乎令人惊讶,例如,如果您正在考虑提供交互式应用程序并以/接近满载运行的服务器的响应能力,以及该响应能力将如何随每台服务器的 CPU 数量而变化。

建议您的工作负载是否有大量线程/进程

我还遇到了 2013 年的建议,对于其他一些设置,如果您的工作负载具有大量线程,则可能会获得显着的吞吐量。(或者更准确地说,它重新获得了他们在 pre-CFS 内核上获得的吞吐量)。

忽略 CONFIG_HZ

我认为您无需担心CONFIG_HZ设置为什么。我的理解是它与当前内核无关,假设您有合理的计时器硬件。另请参阅提交 8f4d37ec073c,“sched:high-res preemption tick”,通过此评论在有关更改的线程中找到:https : //lwn.net/Articles/549754/

(如果您查看提交,我不会担心这SCHED_HRTICK取决于X86。该要求似乎已在最近的一些提交中删除)。