我一直在阅读内核中的 Linux 内核和 CFS 调度程序。我遇到了vruntime(虚拟运行时),它是 CFS 调度程序背后的核心概念。我阅读了“<em>Linux Kernel Development”以及互联网上的其他博客,但无法理解vruntime背后的基本计算。vruntime属于特定进程还是属于具有相同 nice 值的一组进程。什么是加权因子,它是如何计算的?我经历了所有这些概念,但无法理解。另外,vruntime和 *min_vruntime* 有什么区别?
2 回答
vruntime 是每个线程的;它是嵌套在 task_struct 中的成员。
从本质上讲,vruntime 是线程“运行时间”的度量——它在处理器上花费的时间量。CFS 的重点是对所有人公平;因此,算法归结为一个简单的事情:(在给定运行队列上的任务中)具有最低 vruntime 的任务是最值得运行的任务,因此选择它作为“下一个”。(为了提高效率,实际实现是使用 rbtree 完成的)。
考虑到各种因素——比如优先级、nice value、cgroups 等——vruntime 的计算并不像简单的增量那样直接。我建议阅读“Professional Linux Kernel Architecture”,Mauerer,Wrox Press中的相关部分——它的解释非常详细。
请在下面快速尝试总结其中的一些内容。
其他资源: Documentation/scheduler/sched-design-CFS.txt
快速总结 - vruntime 计算:( 基于本书)
大部分工作在 kernel/sched_fair.c:__update_curr() 中完成
在计时器滴答时调用
更新“当前”刚刚在处理器上花费的物理和虚拟时间
对于以默认优先级运行的任务,即nice value 0,所花费的物理时间和虚拟时间相同
对于其他优先级(良好)级别的任务,情况并非如此;因此 vruntime 的计算受当前使用负载权重因子的优先级影响
delta_exec = (unsigned long)(现在 - curr->exec_start); // ... delta_exec_weighted = calc_delta_fair(delta_exec, curr); curr->vruntime += delta_exec_weighted;
忽略一些舍入和溢出检查,calc_delta_fair 所做的是计算以下公式给出的值:
delta_exec_weighed = delta_exec * (NICE_0_LOAD / curr->load.weight)
问题是,更重要的任务(nice 值较低的任务)将具有更大的权重;因此,通过上述等式,占他们的 vruntime 将更小(因此让他们在 rbtree 的左侧排队更多!)。
vruntime 是进程的虚拟运行时,它有助于跟踪进程运行了多少时间。vruntime 是定义在 include/linux/sched.h 中的 sched_entity 结构的成员
min_vruntime 表示 cfs 运行队列的最小 vruntime。它表示在该 cfs 运行队列上调度的所有进程的 vruntime 的最小值。min_vruntime 是定义在 include/linux/sched.h 中的 cfs_rq 结构的成员
min_vruntime 的目的是选择 cfs 运行队列中的下一个进程运行。为了对所有进程公平,CFS 调度程序选择具有最小 vruntime 的进程首先执行。
include/linux/sched.h 的链接是:https ://elixir.bootlin.com/linux/latest/source/include/linux/sched.h