PELT (Per Entity Load Tracking)

Linux的Per-entity load tracking(PELT,按实体负载跟踪)是内核中用于更精确地跟踪和管理系统负载的一种机制,以下是相关介绍:

背景及目的

  • 在Linux 3.8版本之前的内核CFS调度器采用的是跟踪每个运行队列上的负载(per-rq load tracking),无法准确得知当前CPU上的负载来自哪些任务、每个任务施加多少负载等信息,难以实现更精细的负载均衡和CPU算力调整。
  • PELT算法把负载跟踪从per-rq推进到per-entity的层次,让调度器能获取每个调度实体(进程或控制组中的一组进程)对系统负载的贡献,为更精准的调度算法提供支撑。

基本方法

  • 时间划分:将时间分成1024us的序列,在每个周期中计算一个entity对系统负载的贡献。
  • 瞬时负载计算:任务在1024us的周期窗口内的负载即瞬时负载,若在该周期内runnable的时间是t,引入负载权重loadweight,瞬时负载li = loadweight×(t/1024)。
  • 瞬时利用率计算:任务的瞬时利用率ui = maxcpucapacity×(t/1024),与任务优先级无关。
  • 平均负载计算:由于瞬时负载和利用率变化快,不适合直接用于调整调度算法,因此需对瞬时负载进行滑动平均计算得到平均负载。一个调度实体的平均负载可以表示为l = l0 + l1×y + l2×y² + l3×y³+…,其中li表示在周期pi中的瞬时负载,y是衰减因子,在目前的内核代码中,y³²等于0.5。

优势

  • 精准负载迁移:在任务迁移时能准确携带其负载信息,避免了之前per-rq跟踪方式下任务迁移时负载计算不准确和可能出现的双重计数问题,使系统全局负载计算更准确,有助于实现更合理的负载均衡。
  • 提供精细调度信息:调度器可以清楚了解每个调度实体的负载情况,根据负载和利用率来更精准地为任务选择合适的CPU,进行迁核或提频等操作,提高系统资源利用率和整体性能,同时有助于实现更优的功耗管理。

实现中的挑战与解决

  • 挑战:非运行状态的实体(如因等待资源而阻塞的进程)也可能对系统负载有贡献,但系统中可能存在大量阻塞实体,若遍历它们来更新负载信息,会带来巨大的性能开销。
  • 解决:在每个CFS_RQ(控制组运行队列)结构中维护一个单独的"blocked load"总和。当进程阻塞时,将其负载从总可运行负载值中减去并添加到阻塞负载中,以与可运行实体负载分开计算和管理,可按相同的衰减因子y进行衰减,当阻塞进程再次变为可运行时,再将其负载进行相应处理。

DVFS

DVFS 即 Dynamic Voltage and Frequency Scaling,意为动态电压和频率缩放。它用于调整 CPU 的电压和频率,以适应不同的工作负载需求,实现性能和功耗的平衡。

  • 在频率 / CPU 不变性部分,由于不同频率下 CPU 的性能表现不同(如在 1GHz 下消耗 50% 的 CPU 与在 2GHz 下消耗 50% 的 CPU 不同),所以允许架构使用 DVFS 比率和微拱形比率来扩展时间增量,使 "运行" 和 "可运行" 指标不受 DVFS 和 CPU 类型的影响,实现指标在不同 CPU 之间的传输和比较12。
  • 在 Schedutil / DVFS 部分,每次调度器负载跟踪更新时,会调用 schedutil 来更新硬件 DVFS 状态,以根据 CPU 运行队列的 "运行" 指标计算所需的频率,进而选择 P-state/OPP 或向硬件发出 CPPC 风格的请求 。在低负载场景下,"运行" 数值能反映利用率,而在饱和场景下任务迁移会使 "运行" 值波动,但时间推移会修正345

DVFS(Dynamic Voltage and Frequency Scaling)即动态电压和频率缩放,工作原理涉及多个方面:

  • 比率计算:对于简单的DVFS架构(软件完全控制),其比率计算为当前频率(f_cur)与最大频率(f_max)的比值,即r_dvfs := f_cur / f_max;对于硬件控制DVFS的动态系统,使用硬件计数器(如Intel APERF/MPERF、ARMv8.4-AMU)来提供比率。以Intel为例,f_cur := APERF / MPERF * P0f_max根据不同情况取值,r_dvfs := min(1, f_cur / f_max),并且选择4C涡轮增压而非1C涡轮增压以使其更具可持续性。
  • 指标调整:通过调整频率,使得 "运行" 和 "可运行" 这两个关键指标能够不受DVFS和CPU类型的影响,即实现频率/CPU不变性。这样可以在不同CPU之间传输和比较这些指标,r_cpu由当前CPU最高性能水平与系统中其他CPU最高性能水平的比率确定,r_tot = r_dvfs * r_cpu,从而使上述指标标准化。
  • 与调度器协同工作:每次调度器负载跟踪更新(如任务唤醒、任务迁移、时间推进)时,会调用schedutil更新硬件DVFS状态。依据CPU运行队列的 "运行" 指标(频率不变的CPU利用率估计值)计算所需频率,计算过程会考虑UTIL_EST、UCLAMP_TASK等因素,最终得到期望频率f_des := min( f_max, 1.25 u * f_max ),该频率用于选择P-state/OPP或直接转化为对硬件的CPPC风格请求。