SCHED_BATCH 描述令人困惑 - 它实际上是做什么的?

Eve*_*ard 6 linux scheduling linux-kernel

Linux 中有多个调度选项,可以借助chrt命令行将其设置为进程。我似乎无法理解其中之一......哪个是SCHED_BATCH。事实上,它的描述在多个来源中都是自相矛盾的。但在此之前,我将总结我设法获得的有关所有计划选项的事实,因为不同的描述引用了SCHED_BATCH它们。

SCHED_FIFO基本上都是SCHED_RR实时调度策略,略有差异,这里大多数没有问题,它们总是先于任何其他进程运行。

SCHED_OTHER是默认策略,根据nice每个进程的值来分配优先级。

SCHED_DEADLINE- 我还没有完全理解这个,它似乎实际上更接近SCHED_FIFO但具有设置的执行计时器,并且如果达到这些计时器,实际上可能会抢占SCHED_FIFO/任务。SCHED_RR

SCHED_IDLE- 基本上“只有在 CPU 空闲时才进行调度”,这里没有问题。

现在,SCHED_BATCH我发现这是很有争议的。一方面,在2002 年的原始实现笔记中,据说它与SCHED_IDLE用户代码和SCHED_OTHER内核代码基本相同(以避免由于进程从未被调度而导致内核资源锁定)。在MAN 文章中,据说它与 基本相同,SCHED_OTHER但有一点小惩罚,因为它被认为是 CPU 限制的。

现在,这两种SCHED_BATCH解释彼此不一致。哪一个是真相?是否SCHED_BATCH在某个地方重新实现了?或者有人SCHED_BATCH在写MAN文章时误解了?哪一种解释是正确的?

更新:额外研究:

我做了更多挖掘,发现了这个内核调度程序文档,还通过挖掘sched 源代码,似乎SCHED_BATCH确实是由与SCHED_OTHER.

我还做了一个测试。我有一个进程实际上限制了其他进程,因为它的负载很高,即使使用很好的 19,但默认SCHED_OTHER设置也是如此。我已将其设置为SCHED_IDLE,其他进程的限制问题消失了...然后我决定尝试SCHED_BATCH相同的进程(具有相同的良好 19 设置)。令人惊讶的是,SCHED_BATCH也没有限制我的其他进程,比如SCHED_IDLE

但从我上面链接的文档看来,SCHED_IDLE也可以通过与SCHED_OTHER和相同的代码来处理SCHED_BATCH,但优先级超低。尽管我仍然有点迷失在哪些情况下它确实使用CFS(这是SCHED_OTHER主要实现),而在哪些情况下它使用kernel/sched/idle.c实现。

我肯定仍然没有任何结论性的答案,测试和文档对我来说仍然没有太大意义。测试表明它的SCHED_BATCH工作方式与实际SCHED_IDLE情况相同,但所有文档都表明它应该像SCHED_OTHER实际情况一样工作!

Flo*_*low 1

SCHED_BATCH

\n

来自man sched(7),关于SCHED_BATCH

\n
\n

\xe2\x80\xa6此策略将导致调度程序始终假定该线程是 CPU 密集型的。因此,调度程序将对唤醒行为应用较小的调度惩罚,以便该线程在调度决策中受到轻微的不利影响。

\n
\n

显然,CFS 调度程序对假定为 CPU 密集型的线程施加了“小惩罚”。查看 Linux 的源代码就会发现,它只SCHED_BATCH影响一个位置的调度程序行为。即kernel/sched/fair.c:yield_task_fair()

\n
static void yield_task_fair(struct rq *rq)\n{\n    \xe2\x80\xa6\n    if (curr->policy != SCHED_BATCH) {\n        update_rq_clock(rq);\n        /*\n         * Update run-time statistics of the \'current\'.\n         */\n        update_curr(cfs_rq);\n        /*\n         * Tell update_rq_clock() that we\'ve just updated,\n         * so we don\'t do microscopic update in schedule()\n         * and double the fastpath cost.\n         */\n        rq_clock_skip_update(rq);\n    }\n\n    set_skip_buddy(se);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

从函数名称来看,它似乎是产生当前线程(并可能选择下一个线程)的函数。当前在 CPU 上运行的线程 ( curr) 会从 CPU 中移除(“让出”),以使 CPU 可供另一个线程使用。如果curr是在调度策略下运行SCHED_BATCH,那么一些运行时的统计信息curr不会更新。

\n

我怀疑,从 CFS 的角度来看,不更新统计信息会导致线程 CPU 密集,这反过来又会使 CFS 不太有利地选择线程。

\n

SCHED_BATCH 与 SCHED_IDLE

\n

SCHED_BATCH至于和的区别SCHED_IDLE: 两者其实是有很大不同的。首先,SCHED_IDLE线程在有空闲 CPU 时运行。因此,线程没有进度保证SCHED_IDLE。如果系统 100% 被其他线程利用,那么SCHED_IDLE线程可能永远不会运行。情况并非如此SCHED_BATCH,线程参与正常的 CPU 多路复用,因此可以保证继续进行。

\n

此外,对于 Linux >= 5.4,SCHED_IDLE从 CFS 调度程序的角度来看,运行线程的 CPU 被视为空闲。这有一个重要的含义:一旦非SCHED_IDLE线程变得可运行,调度程序可能会立即放弃该SCHED_IDLE线程并将非SCHED_IDLE线程放置在其上。另请参阅“修复 SCHED_IDLE”:LWN.net (2019-11-26)

\n

SCHED_BATCH也能够“取消限制”您的其他任务,可能只是因为SCHED_BATCH线程收到的惩罚足以做到这一点。此外,kernel/sched/idle.c与 没有直接关系SCHED_IDLE,该文件仅包含与调度程序相关的代码,用于将 CPU 置于空闲模式。SCHED_OTHERSCHED_BATCH 都是 SCHED_IDLELinux的CFS调度器的调度策略( kernel/sched/fair.c)。

\n