【 SCHED 】聊聊 PELT 负载计算
What’s PELT
所谓 PELT,其为 Per-entity load tracking,可理解为它是一个负载计算的算法,它在 kernel 3.8 版本被引入来取代以往的算法。
如果想加深对 PELT 的理解,那就得追溯一下历史,究竟是怎么背景才旦生出 PELT 的呢?
之所以存在负载计算,是因为在 SMP 架构上,为了避免”一核有难,七核围观“的囧境,我们需要得知每个核的运行状态是怎么样,当前核对应的运行队列中的任务量是否庞大 …
以往负载计算的处理方式是,它会关注每个运行队列,并掌握每个运行队列的负载大小,
那么 PELT 这时迎难而上,基于每个 entity 来计算负载,统计的粒度更加细化,更有助于做均衡处理,而 entity 不仅仅是一个 task,要知道 CFS 调度器还支持组调度(task group),而它也被看作是一个 entity。
为了做到 Per-entity 的负载跟踪,时间被分成了 1024us 的序列,在每一个 1024us 的周期中,一个 entity 对系统负载的贡献可以根据该实体处于就绪状态(包含运行态)的时间进行计算。如果在该周期内就绪的时间是 x,那么对系统负载的贡献就是 x / 1024,
如果一个任务在最近三个周期内的就绪时间分别为 P0、P1、P2,如下图所示,
那么根据 PELT,即可得出该任务当前负载 U’ 如下,U 为之前负载值,
U’ = P0 + P1y^0 + P2y^2 + U*y^3 + …
上式即为 PELT 的灵魂所在,本篇的一大重点就是要阐述出在 kernel 中在怎么得出上式的。
那我们就从这个核心出发,看看如果用源码来实现 PELT,我们直接抛出 CORE,它就是 accumulate_sum