调度器之CAS调度

Capacity Aware Scheduling

1.CPU容量

1.1 介绍

传统的同质SMP平台由完全相同的CPU组成,相对应的异构平台由具有不同性能特征的CPU组成——在这样的平台上,并非所有CPU的能力都是一样的。
CPU容量是衡量CPU所能达到的性能的指标,与系统中性能最高的CPU进行标准化。异构系统也称为非对称CPU容量系统,因为它们包含不同容量的CPU。
最大可实现性能(最大CPU容量IOW)的差异源于两个因素:

  • 并非所有CPU都具有相同的微体系结构(µarch)。
  • 使用动态电压和频率缩放(DVFS),并非所有CPU都能够在物理上获得更高的操作性能点(OPP)

ARM的大小核架构就是就是这两者的一个例子。大核CPU比小核CPU更注重性能(更多的流水线级、更大的缓存、更智能的预测器等),通常可以达到比小核CPU高的OPP。
CPU性能通常以每秒百万条指令(MIPS)表示,也可以表示为每Hz可获得的给定指令量,导致:

capacity(cpu) = work_per_hz(cpu) * max_freq(cpu)

1. 2 调度器相关术语

调度程序中使用了两个不同的容量值。CPU的“capacity_orig”是其最大可达到的容量,即其最大可实现的性能水平。CPU的“容量”是其“capacity_orig”,减去可用性能的一些损失(例如处理IRQ所花费的时间)。(个人理解:因为中断处理的代码,不在调度器的统计之中,所以计算CPU上的rq队列中的算力消耗的时候,漏掉了irq的处理部分)

请注意,CPU的“capacity”仅用于CFS类,而“capacity_orig”与类无关。为简明起见,本文档的其余部分将使用术语“capacity”代表了“capacity_orig”的含义。

1.3 平台举例

1.3.1 相同的OPP

考虑一个假设的双核非对称CPU容量系统,其中

> work_per_hz(CPU0) = W
> work_per_hz(CPU1) = W/2
> 所有CPU都以相同的固定频率运行

根据上述容量定义:

> 容量(CPU0)=C
> 容量(CPU1)=C/2

根据大小核的概念,我们可以将CPU0当做大核,CPU1当做小核。
对于定期执行固定工作量的工作负载,您将得到如下执行跟踪:
在这里插入图片描述
CPU0具有系统(C)中最高的容量,并在T个时间单位内完成固定量的工作W。另一方面,CPU1的容量是CPU0的一半,因此在T中只完成W/2。

1.3.2 不同的最大OPP

通常,不同容量值的CPU也具有不同的最大OPP。考虑与上面相同的CPU(即相同的work_per_hz()):

> max_freq(CPU0) = F
> max_freq(CPU1) = 2/3 * F

这将导致:

> capacity(CPU0) = C
> capacity(CPU1) = C/3

执行与上面所述相同的工作负载,每个CPU以其最大频率运行会导致:
在这里插入图片描述

1.4 重要说明

应该注意的是,使用单个值来表示CPU性能的差异可能不是很准确。两个不同架构之间的相对性能差异可能是,整数运算的X%,浮点运算的Y%,分支运算的Z%,等等。不过,使用这种简单方法的结果目前还是令人满意的。

2. 任务利用率

2.1 简介

容量感知调度(CAS)需要描述任务对CPU容量的要求。每个调度器类都可以用不同的方式表达这一点,虽然任务利用率是CFS特有的,但为了引入更通用的概念,在这里借用任务使用率描述它会更方便。
任务利用率是表示任务所需要的吞吐量的百分比。它的一个简单近似值是任务的占空比,即:

task_util(p) = duty_cycle(p)

在具有固定频率的SMP系统上,100%的利用率表明任务是繁忙执行周期。相反,10%的利用率意味着这是一个周期性轻量任务,它的睡眠时间比执行时间长。可变的CPU频率和不对称的CPU容量使这一点复杂化;以下部分将对这些进行扩展。

2.2 频率不变性

需要考虑的一个问题是,工作负载的占空比直接受到CPU当前运行的OPP的影响。考虑以给定频率F运行周期性工作负载:
在这里插入图片描述
这种情况下 duty_cycle(p) == 25%.
现在,考虑以频率F/2运行相同的工作负载:
在这里插入图片描述
这种情况下,尽管任务在两次执行中具有完全相同的行为(即执行相同的工作量)但是这次的duty_cycle(p)==50%

task_util_freq_inv(p) = duty_cycle(p) * (curr_frequency(cpu) / max_frequency(cpu))

将此公式应用于上述两个示例,将因为评率不同产生25%的利用率的差异。

2.3 CPU不变性

CPU容量对任务利用率有类似的影响,因为在不同容量值的CPU上运行相同的工作负载将产生不同的占空比。
考虑1.3.1的情况

容量(CPU0)=C
容量(CPU1)=C/3

在每个CPU上以最大频率执行给定的周期性工作负载将导致:
在这里插入图片描述
换句话说:

如果p以其最大频率在CPU0上运行,duty_cycle(p)==25%
如果p以其最大频率在CPU1上运行,duty_cycle(p)==75%

可以使用以下公式使任务利用率在不同的CPU上保持不变:

task_util_cpu_inv(p) = duty_cycle(p) * (capacity(cpu) / max_capacity)

其中“max_capacity”是系统中最高的CPU容量值。将此公式应用于上面的示例,两种情况下都得到25%的CPU利用率。

2.4 不变的任务利用率

为了获得一致性的结果,需要将频率和CPU不变性应用于任务利用率。因此,对于给定任务p,CPU和频率不变的任务利用率的伪公式为:
在这里插入图片描述
换句话说,不变任务利用率描述了一个任务在容量最高的CPU上以最大的频率运行时的使用率。以下章节中提到的任务利用率默认都是按照这个公式进行定义的。

2.5 利用率估算

如果没有crystal ball,任务行为(以及任务利用率)就无法在任务首次可运行时准确预测。CFS类基于PELT机制维护少量CPU和任务信号,计算出一个平均利用率(而不是瞬时利用率)。
这意味着,尽管将考虑“真实”任务利用率(使用crystal ball)来编写容量感知调度标准,但实际实现时我们只能通过某种方式进行估算起任务使用率。

3.1 CAS的需求

3.1 CPU容量

Linux目前无法自行计算CPU容量,因此必须从系统架构arch中获取这个值。arch必须定义arch_scale_cpu_capacity()。
下面是高通8450架构中定义的这个函数。代码路径:/kernel_platform/msm-kernel/include/linux/arch_topology.h

20  static inline unsigned long topology_get_cpu_scale(int cpu)
21  {
22  	return per_cpu(cpu_scale, cpu);
23  }

3.2频率不变性

如2.2所述,容量感知调度需要频率不变的任务利用率。架构必须为此定义arch_scale_freq_capacity(cpu)。
实现此功能需要确定每个CPU的运行频率。实现这一点的一种方法是利用硬件计数器,其递增速率随CPU的当前频率而变化(x86上的APERF/MPERF,arm64上的AMU)。另一种方法是,当内核意识到切换到的频率(arm/arm64也使用)时,直接使用cpufreq frequency的信息。

下面是高通8450架构中定义的这个函数。代码路径:/kernel_platform/msm-kernel/include/linux/arch_topology.h

29  static inline unsigned long topology_get_freq_scale(int cpu)
30  {
31  	return per_cpu(freq_scale, cpu);
32  }

4.调度器拓扑

在构建调度域的过程中,调度器将确定系统是否具有非对称的CPU容量。也就是需要符合下面两个条件:

检查sched_asym_cpucapacity静态关键字是否被使能。
SD_ASYM_CPUCAPACITY标志将设置在最低的sched_domain级别,也就是说这个级别只包含了一个容量级别而没有跨越多个容量级别。

sched_asym_cpucapacity静态关键字用于保护非对称CPU容量系统的代码段。但是,请注意,所述关键字是“系统范围”的。假设CPUSET有如下设置:
在这里插入图片描述
可以通过如下命令的配置,达到这个目的

  mkdir /sys/fs/cgroup/cpuset/cs0
  echo 0-1 > /sys/fs/cgroup/cpuset/cs0/cpuset.cpus
  echo 0 > /sys/fs/cgroup/cpuset/cs0/cpuset.mems

  mkdir /sys/fs/cgroup/cpuset/cs1
  echo 2-7 > /sys/fs/cgroup/cpuset/cs1/cpuset.cpus
  echo 0 > /sys/fs/cgroup/cpuset/cs1/cpuset.mems

  echo 0 > /sys/fs/cgroup/cpuset/cpuset.sched_load_balance

由于系统中存在*CPU容量不对称,将启用sched_asym_cpucapacity静态关键字。然而,CPU 0-1的sched_domain层次结构只包含了一个容量值,SD_ASYM_CPUCAPACITY没有在该层次结构中被设置,它描述了一个SMP孤岛,所以不应该把它当做非对称容量来处理。
因此,用于保护满足不对称CPU容量的代码路径的“规范”模式是:检查sched_asym_cpucapacity静态关键字如果已启用,则还检查sched_domain层次结构中是否存在SD_asym_cpucapacity(如果设置,即代码路径针对特定CPU或其组)

5.容量感知调度实现

5.1 CFS

5.1.1 容量适应性

CFS的主要容量调度标准为:

task_util(p) < capacity(task_cpu(p))

这通常被称为容量适合性标准,即CFS必须确保任务“适合”其CPU。如果不满足这个条件,也就是CPU运行到最大频率的情况下,也不能满足任务的容量,这被称为CPU-bound。
此外,uclamp允许用户空间通过sched_setattr()或cgroup接口(请参阅Documentation/admin-guide/cgroup-v2.rst)为任务指定最小和最大利用率值。顾名思义,这可以用于将task_util()限制在前面的标准中。

5.1.2唤醒CPU选择

CFS任务唤醒CPU选择遵循上述容量适应标准。最重要的是,uclamp用于限制任务利用率值,这让用户空间在CFS任务的CPU选择上有更多的优势。也就是说,CFS唤醒CPU选择搜索满足以下条件的CPU:

clamp(task_util(p), task_uclamp_min(p), task_uclamp_max(p)) < capacity(cpu)

使用uclamp,用户空间可以通过设置一个比较低的uclamp.max,使本来使用率100%的任务跑在任何一个CPU上;或者设置一个比较大的uclamp.max,让使用率10%的任务执行在高性能的CPU上。
CFS中的唤醒CPU选择可能会被能量感知调度(EAS)所体会,这在Documentation/scheduler/sched-Energy.rst中有描述。

5.1.3负载平衡

唤醒CPU选择中的一种有问题情况就是,一个任务很少睡眠(如果有的话)时,因此也很少走到唤醒流程。考虑:

  w == wakeup event

  capacity(CPU0) = C
  capacity(CPU1) = C / 3

在这里插入图片描述
本来这个任务应该运行在CPU0上,但是出现了下面的情况:

从一开始就计划不正确(初始利用率估计不准确)
从一开始就正确安排了,但突然需要更多的处理能力

那么就可能变成了CPU受限了。也就是说 task_util(p) > capacity(task_cpu(p))
CPU容量调度标准被违反,并且可能不再有任何唤醒事件来通过唤醒CPU选择来解决此问题。
在这种情况下的任务被称为“不匹配”任务。利用CFS负载均衡器,可以讲不合适的任务迁移到合适的CPU上,更具体地说是进行主动负载平衡(它适合迁移当前正在运行的任务)。当负载平衡发生时,如果不匹配任务可以迁移到容量大于当前容量的CPU,则将触发不匹配活动负载平衡。

5.2 RT调度

5.2.1唤醒CPU选择

RT任务唤醒CPU选择搜索满足以下条件的CPU:task_uclamp_min(p) <= capacity(task_cpu(cpu))
同时仍然遵循通常的优先级约束。如果没有一个候选CPU能够满足这个容量标准,那么将遵循严格的基于优先级的调度,并忽略CPU容量。

5.3 DL调度

5.3.1唤醒CPU选择

DL任务唤醒CPU选择搜索满足以下条件的CPU:task_uclamp_min(p) <= capacity(task_cpu(cpu))
同时仍然遵守通常的带宽和期限限制。如果没有一个候选CPU能够满足此容量标准,则任务将保留在其当前CPU上。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值