cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sched-capacity.rst (15589B)


      1.. SPDX-License-Identifier: GPL-2.0
      2.. include:: ../disclaimer-zh_CN.rst
      3
      4:Original: Documentation/scheduler/sched-capacity.rst
      5
      6:翻译:
      7
      8  唐艺舟 Tang Yizhou <tangyeechou@gmail.com>
      9
     10:校译:
     11
     12  时奎亮 Alex Shi <alexs@kernel.org>
     13
     14=============
     15算力感知调度
     16=============
     17
     181. CPU算力
     19==========
     20
     211.1 简介
     22--------
     23
     24一般来说,同构的SMP平台由完全相同的CPU构成。异构的平台则由性能特征不同的CPU构成,在这样的
     25平台中,CPU不能被认为是相同的。
     26
     27我们引入CPU算力(capacity)的概念来测量每个CPU能达到的性能,它的值相对系统中性能最强的CPU
     28做过归一化处理。异构系统也被称为非对称CPU算力系统,因为它们由不同算力的CPU组成。
     29
     30最大可达性能(换言之,最大CPU算力)的差异有两个主要来源:
     31
     32- 不是所有CPU的微架构都相同。
     33- 在动态电压频率升降(Dynamic Voltage and Frequency Scaling,DVFS)框架中,不是所有的CPU都
     34  能达到一样高的操作性能值(Operating Performance Points,OPP。译注,也就是“频率-电压”对)。
     35
     36Arm大小核(big.LITTLE)系统是同时具有两种差异的一个例子。相较小核,大核面向性能(拥有更多的
     37流水线层级,更大的缓存,更智能的分支预测器等),通常可以达到更高的操作性能值。
     38
     39CPU性能通常由每秒百万指令(Millions of Instructions Per Second,MIPS)表示,也可表示为
     40per Hz能执行的指令数,故::
     41
     42  capacity(cpu) = work_per_hz(cpu) * max_freq(cpu)
     43
     441.2 调度器术语
     45--------------
     46
     47调度器使用了两种不同的算力值。CPU的 ``capacity_orig`` 是它的最大可达算力,即最大可达性能等级。
     48CPU的 ``capacity`` 是 ``capacity_orig`` 扣除了一些性能损失(比如处理中断的耗时)的值。
     49
     50注意CPU的 ``capacity`` 仅仅被设计用于CFS调度类,而 ``capacity_orig`` 是不感知调度类的。为
     51简洁起见,本文档的剩余部分将不加区分的使用术语 ``capacity`` 和 ``capacity_orig`` 。
     52
     531.3 平台示例
     54------------
     55
     561.3.1 操作性能值相同
     57~~~~~~~~~~~~~~~~~~~~
     58
     59考虑一个假想的双核非对称CPU算力系统,其中
     60
     61- work_per_hz(CPU0) = W
     62- work_per_hz(CPU1) = W/2
     63- 所有CPU以相同的固定频率运行
     64
     65根据上文对算力的定义:
     66
     67- capacity(CPU0) = C
     68- capacity(CPU1) = C/2
     69
     70若这是Arm大小核系统,那么CPU0是大核,而CPU1是小核。
     71
     72考虑一种周期性产生固定工作量的工作负载,你将会得到类似下图的执行轨迹::
     73
     74 CPU0 work ^
     75           |     ____                ____                ____
     76           |    |    |              |    |              |    |
     77           +----+----+----+----+----+----+----+----+----+----+-> time
     78
     79 CPU1 work ^
     80           |     _________           _________           ____
     81           |    |         |         |         |         |
     82           +----+----+----+----+----+----+----+----+----+----+-> time
     83
     84CPU0在系统中具有最高算力(C),它使用T个单位时间完成固定工作量W。另一方面,CPU1只有CPU0一半
     85算力,因此在T个单位时间内仅完成工作量W/2。
     86
     871.3.2 最大操作性能值不同
     88~~~~~~~~~~~~~~~~~~~~~~~~
     89
     90具有不同算力值的CPU,通常来说最大操作性能值也不同。考虑上一小节提到的CPU(也就是说,
     91work_per_hz()相同):
     92
     93- max_freq(CPU0) = F
     94- max_freq(CPU1) = 2/3 * F
     95
     96这将推出:
     97
     98- capacity(CPU0) = C
     99- capacity(CPU1) = C/3
    100
    101执行1.3.1节描述的工作负载,每个CPU按最大频率运行,结果为::
    102
    103 CPU0 work ^
    104           |     ____                ____                ____
    105           |    |    |              |    |              |    |
    106           +----+----+----+----+----+----+----+----+----+----+-> time
    107
    108                            workload on CPU1
    109 CPU1 work ^
    110           |     ______________      ______________      ____
    111           |    |              |    |              |    |
    112           +----+----+----+----+----+----+----+----+----+----+-> time
    113
    1141.4 关于计算方式的注意事项
    115--------------------------
    116
    117需要注意的是,使用单一值来表示CPU性能的差异是有些争议的。两个不同的微架构的相对性能差异应该
    118描述为:X%整数运算差异,Y%浮点数运算差异,Z%分支跳转差异,等等。尽管如此,使用简单计算方式
    119的结果目前还是令人满意的。
    120
    1212. 任务使用率
    122=============
    123
    1242.1 简介
    125--------
    126
    127算力感知调度要求描述任务需求,描述方式要和CPU算力相关。每个调度类可以用不同的方式描述它。
    128任务使用率是CFS独有的描述方式,不过在这里介绍它有助于引入更多一般性的概念。
    129
    130任务使用率是一种用百分比来描述任务吞吐率需求的方式。一个简单的近似是任务的占空比,也就是说::
    131
    132  task_util(p) = duty_cycle(p)
    133
    134在频率固定的SMP系统中,100%的利用率意味着任务是忙等待循环。反之,10%的利用率暗示这是一个
    135小周期任务,它在睡眠上花费的时间比执行更多。
    136
    1372.2 频率不变性
    138--------------
    139
    140一个需要考虑的议题是,工作负载的占空比受CPU正在运行的操作性能值直接影响。考虑以给定的频率F
    141执行周期性工作负载::
    142
    143  CPU work ^
    144           |     ____                ____                ____
    145           |    |    |              |    |              |    |
    146           +----+----+----+----+----+----+----+----+----+----+-> time
    147
    148可以算出 duty_cycle(p) == 25%。
    149
    150现在,考虑以给定频率F/2执行 *同一个* 工作负载::
    151
    152  CPU work ^
    153           |     _________           _________           ____
    154           |    |         |         |         |         |
    155           +----+----+----+----+----+----+----+----+----+----+-> time
    156
    157可以算出 duty_cycle(p) == 50%,尽管两次执行中,任务的行为完全一致(也就是说,执行的工作量
    158相同)。
    159
    160任务利用率信号可按下面公式处理成频率不变的(译注:这里的术语用到了信号与系统的概念)::
    161
    162  task_util_freq_inv(p) = duty_cycle(p) * (curr_frequency(cpu) / max_frequency(cpu))
    163
    164对上面两个例子运用该公式,可以算出频率不变的任务利用率均为25%。
    165
    1662.3 CPU不变性
    167-------------
    168
    169CPU算力与任务利用率具有类型的效应,在算力不同的CPU上执行完全相同的工作负载,将算出不同的
    170占空比。
    171
    172考虑1.3.2节提到的系统,也就是说::
    173
    174- capacity(CPU0) = C
    175- capacity(CPU1) = C/3
    176
    177每个CPU按最大频率执行指定周期性工作负载,结果为::
    178
    179 CPU0 work ^
    180           |     ____                ____                ____
    181           |    |    |              |    |              |    |
    182           +----+----+----+----+----+----+----+----+----+----+-> time
    183
    184 CPU1 work ^
    185           |     ______________      ______________      ____
    186           |    |              |    |              |    |
    187           +----+----+----+----+----+----+----+----+----+----+-> time
    188
    189也就是说,
    190
    191- duty_cycle(p) == 25%,如果任务p在CPU0上按最大频率运行。
    192- duty_cycle(p) == 75%,如果任务p在CPU1上按最大频率运行。
    193
    194任务利用率信号可按下面公式处理成CPU算力不变的::
    195
    196  task_util_cpu_inv(p) = duty_cycle(p) * (capacity(cpu) / max_capacity)
    197
    198其中 ``max_capacity`` 是系统中最高的CPU算力。对上面的例子运用该公式,可以算出CPU算力不变
    199的任务利用率均为25%。
    200
    2012.4 任务利用率不变量
    202--------------------
    203
    204频率和CPU算力不变性都需要被应用到任务利用率的计算中,以便求出真正的不变信号。
    205任务利用率的伪计算公式是同时具备CPU和频率不变性的,也就是说,对于指定任务p::
    206
    207                                     curr_frequency(cpu)   capacity(cpu)
    208  task_util_inv(p) = duty_cycle(p) * ------------------- * -------------
    209                                     max_frequency(cpu)    max_capacity
    210
    211也就是说,任务利用率不变量假定任务在系统中最高算力CPU上以最高频率运行,以此描述任务的行为。
    212
    213在接下来的章节中提到的任何任务利用率,均是不变量的形式。
    214
    2152.5 利用率估算
    216--------------
    217
    218由于预测未来的水晶球不存在,当任务第一次变成可运行时,任务的行为和任务利用率均不能被准确预测。
    219CFS调度类基于实体负载跟踪机制(Per-Entity Load Tracking, PELT)维护了少量CPU和任务信号,
    220其中之一可以算出平均利用率(与瞬时相反)。
    221
    222这意味着,尽管运用“真实的”任务利用率(凭借水晶球)写出算力感知调度的准则,但是它的实现将只能
    223用任务利用率的估算值。
    224
    2253. 算力感知调度的需求
    226=====================
    227
    2283.1 CPU算力
    229-----------
    230
    231当前,Linux无法凭自身算出CPU算力,因此必须要有把这个信息传递给Linux的方式。每个架构必须为此
    232定义arch_scale_cpu_capacity()函数。
    233
    234arm和arm64架构直接把这个信息映射到arch_topology驱动的CPU scaling数据中(译注:参考
    235arch_topology.h的percpu变量cpu_scale),它是从capacity-dmips-mhz CPU binding中衍生计算
    236出来的。参见Documentation/devicetree/bindings/arm/cpu-capacity.txt。
    237
    2383.2 频率不变性
    239--------------
    240
    241如2.2节所述,算力感知调度需要频率不变的任务利用率。每个架构必须为此定义
    242arch_scale_freq_capacity(cpu)函数。
    243
    244实现该函数要求计算出每个CPU当前以什么频率在运行。实现它的一种方式是利用硬件计数器(x86的
    245APERF/MPERF,arm64的AMU),它能按CPU当前频率动态可扩展地升降递增计数器的速率。另一种方式是
    246在cpufreq频率变化时直接使用钩子函数,内核此时感知到将要被切换的频率(也被arm/arm64实现了)。
    247
    2484. 调度器拓扑结构
    249=================
    250
    251在构建调度域时,调度器将会发现系统是否表现为非对称CPU算力。如果是,那么:
    252
    253- sched_asym_cpucapacity静态键(static key)将使能。
    254- SD_ASYM_CPUCAPACITY_FULL标志位将在尽量最低调度域层级中被设置,同时要满足条件:调度域恰好
    255  完整包含某个CPU算力值的全部CPU。
    256- SD_ASYM_CPUCAPACITY标志将在所有包含非对称CPU的调度域中被设置。
    257
    258sched_asym_cpucapacity静态键的设计意图是,保护为非对称CPU算力系统所准备的代码。不过要注意的
    259是,这个键是系统范围可见的。想象下面使用了cpuset的步骤::
    260
    261  capacity    C/2          C
    262            ________    ________
    263           /        \  /        \
    264  CPUs     0  1  2  3  4  5  6  7
    265           \__/  \______________/
    266  cpusets   cs0         cs1
    267
    268可以通过下面的方式创建:
    269
    270.. code-block:: sh
    271
    272  mkdir /sys/fs/cgroup/cpuset/cs0
    273  echo 0-1 > /sys/fs/cgroup/cpuset/cs0/cpuset.cpus
    274  echo 0 > /sys/fs/cgroup/cpuset/cs0/cpuset.mems
    275
    276  mkdir /sys/fs/cgroup/cpuset/cs1
    277  echo 2-7 > /sys/fs/cgroup/cpuset/cs1/cpuset.cpus
    278  echo 0 > /sys/fs/cgroup/cpuset/cs1/cpuset.mems
    279
    280  echo 0 > /sys/fs/cgroup/cpuset/cpuset.sched_load_balance
    281
    282由于“这是”非对称CPU算力系统,sched_asym_cpucapacity静态键将使能。然而,CPU 0--1对应的
    283调度域层级,算力值仅有一个,该层级中SD_ASYM_CPUCAPACITY未被设置,它描述的是一个SMP区域,也
    284应该被以此处理。
    285
    286因此,“典型的”保护非对称CPU算力代码路径的代码模式是:
    287
    288- 检查sched_asym_cpucapacity静态键
    289- 如果它被使能,接着检查调度域层级中SD_ASYM_CPUCAPACITY标志位是否出现
    290
    2915. 算力感知调度的实现
    292=====================
    293
    2945.1 CFS
    295-------
    296
    2975.1.1 算力适应性(fitness)
    298~~~~~~~~~~~~~~~~~~~~~~~~~~~
    299
    300CFS最主要的算力调度准则是::
    301
    302  task_util(p) < capacity(task_cpu(p))
    303
    304它通常被称为算力适应性准则。也就是说,CFS必须保证任务“适合”在某个CPU上运行。如果准则被违反,
    305任务将要更长地消耗该CPU,任务是CPU受限的(CPU-bound)。
    306
    307此外,uclamp允许用户空间指定任务的最小和最大利用率,要么以sched_setattr()的方式,要么以
    308cgroup接口的方式(参阅Documentation/admin-guide/cgroup-v2.rst)。如其名字所暗示,uclamp
    309可以被用在前一条准则中限制task_util()。
    310
    3115.1.2 被唤醒任务的CPU选择
    312~~~~~~~~~~~~~~~~~~~~~~~~~
    313
    314CFS任务唤醒的CPU选择,遵循上面描述的算力适应性准则。在此之上,uclamp被用来限制任务利用率,
    315这令用户空间对CFS任务的CPU选择有更多的控制。也就是说,CFS被唤醒任务的CPU选择,搜索满足以下
    316条件的CPU::
    317
    318  clamp(task_util(p), task_uclamp_min(p), task_uclamp_max(p)) < capacity(cpu)
    319
    320通过使用uclamp,举例来说,用户空间可以允许忙等待循环(100%使用率)在任意CPU上运行,只要给
    321它设置低的uclamp.max值。相反,uclamp能强制一个小的周期性任务(比如,10%利用率)在最高性能
    322的CPU上运行,只要给它设置高的uclamp.min值。
    323
    324.. note::
    325
    326  CFS的被唤醒的任务的CPU选择,可被能耗感知调度(Energy Aware Scheduling,EAS)覆盖,在
    327  Documentation/scheduler/sched-energy.rst中描述。
    328
    3295.1.3 负载均衡
    330~~~~~~~~~~~~~~
    331
    332被唤醒任务的CPU选择的一个病理性的例子是,任务几乎不睡眠,那么也几乎不发生唤醒。考虑::
    333
    334  w == wakeup event
    335
    336  capacity(CPU0) = C
    337  capacity(CPU1) = C / 3
    338
    339                           workload on CPU0
    340  CPU work ^
    341           |     _________           _________           ____
    342           |    |         |         |         |         |
    343           +----+----+----+----+----+----+----+----+----+----+-> time
    344                w                   w                   w
    345
    346                           workload on CPU1
    347  CPU work ^
    348           |     ____________________________________________
    349           |    |
    350           +----+----+----+----+----+----+----+----+----+----+->
    351                w
    352
    353该工作负载应该在CPU0上运行,不过如果任务满足以下条件之一:
    354
    355- 一开始发生不合适的调度(不准确的初始利用率估计)
    356- 一开始调度正确,但突然需要更多的处理器功率
    357
    358则任务可能变为CPU受限的,也就是说 ``task_util(p) > capacity(task_cpu(p))`` ;CPU算力
    359调度准则被违反,将不会有任何唤醒事件来修复这个错误的CPU选择。
    360
    361这种场景下的任务被称为“不合适的”(misfit)任务,处理这个场景的机制同样也以此命名。Misfit
    362任务迁移借助CFS负载均衡器,更明确的说,是主动负载均衡的部分(用来迁移正在运行的任务)。
    363当发生负载均衡时,如果一个misfit任务可以被迁移到一个相较当前运行的CPU具有更高算力的CPU上,
    364那么misfit任务的主动负载均衡将被触发。
    365
    3665.2 实时调度
    367------------
    368
    3695.2.1 被唤醒任务的CPU选择
    370~~~~~~~~~~~~~~~~~~~~~~~~~
    371
    372实时任务唤醒时的CPU选择,搜索满足以下条件的CPU::
    373
    374  task_uclamp_min(p) <= capacity(task_cpu(cpu))
    375
    376同时仍然允许接着使用常规的优先级限制。如果没有CPU能满足这个算力准则,那么将使用基于严格
    377优先级的调度,CPU算力将被忽略。
    378
    3795.3 最后期限调度
    380----------------
    381
    3825.3.1 被唤醒任务的CPU选择
    383~~~~~~~~~~~~~~~~~~~~~~~~~
    384
    385最后期限任务唤醒时的CPU选择,搜索满足以下条件的CPU::
    386
    387  task_bandwidth(p) < capacity(task_cpu(p))
    388
    389同时仍然允许接着使用常规的带宽和截止期限限制。如果没有CPU能满足这个算力准则,那么任务依然
    390在当前CPU队列中。