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