LWN:OSPM 2025 报道——第三天!

关注了就能看到更多这么棒的文章哦~

Reports from OSPM 2025, day three

By Jonathan Corbet
May 30, 2025
OSPM
Gemini flash translation
https://lwn.net/Articles/1022054/

第七届 Linux 内核电源管理与调度峰会(简称 "OSPM")于 2025 年 3 月 18 日至 20 日举行。第三天(也是最后一天)讨论的主题包括代理执行(proxy execution)、能源感知调度(energy-aware scheduling)、截止时间调度器(deadline scheduler),以及对 内核 EEVDF 调度器 的评估。

和 第一天 以及 第二天 的报道一样,每份报告都由署名演讲者撰写。

你们还没听腻代理执行的分享吗?

演讲者:John Stultz (视频)

在 OSPM 和 Linux Plumbers Conference (LPC) 会议上,代理执行 (proxy execution) 多年来一直是 一个 持续 讨论的 话题,之一。John Stultz 做了一个题为“你们还没听腻代理执行的分享吗?”的演讲。虽然一些听众善意地表达了相反的看法,但 Stultz 在演讲前提到,做了几年关于这个话题的演讲后,至少  自己有点厌倦了。

演讲首先快速回顾了为什么为代理执行付出这么多持续努力是值得的:它解决了在使用 cpu.shares 、CFS 带宽限制、cpusets 或 SCHED_IDLE 等方法限制后台任务使其不影响前台任务时, SCHED_NORMAL 任务中常见的优先级反转(priority inversion)问题。如果其中一个后台任务在被抢占之前调用进入内核并获取了一个内核互斥锁(mutex),它可能会阻塞需要该内核互斥锁的重要前台任务的运行,从而导致用户可见的不可接受的停顿。

代理执行使用一种优先级继承(priority inheritance)的形式解决了这个问题。它不是跟踪线性的优先级顺序(这种方式只适用于实时任务),而是将被互斥锁阻塞的任务保留在就绪队列(run queue)上;如果重要的被互斥锁阻塞的任务被选中进行调度,调度器会找到锁的持有者并转而运行该任务。这安全地启用了上述功能来限制后台任务,并且在许多示例测试中显示,显著减少了前台任务的异常延迟,为用户提供了更一致的行为。

Stultz 重点介绍了自 他在 2024 年 LPC 上的演讲 以来取得的一些进展。几个月来反复提交的准备性补丁最终被合入(merged)。该系列补丁的下一部分,侧重于仅当锁的持有者与等待者在同一就绪队列上时才进行代理,已经提交了几次并收到了有益的评审反馈。最后,完整的代理执行补丁系列(v14 版本)被合入到 android16-6.12 分支(默认禁用),以便厂商可以进行实验并更新其供应商钩子(vendor hooks),以支持调度和执行上下文分离的概念。

由于整个补丁系列很复杂,Stultz 一直试图将其分成较小的、易于评审的部分提交。他概述了整个补丁系列当前的阶段,目前正在评审的是“单就绪队列代理”(single-run-queue proxying)步骤。接下来是“代理迁移和返回迁移”(proxy-migration and return-migration),然后是“休眠持有者入队和激活”(sleeping owner enqueuing and activation),最后是“链式迁移”(chain migration)。

Stultz 介绍了 补丁集最新版本(演讲时为 v15) 的重点内容、一些近期待办事项以及今年的更大计划。接着,为了讨论,他谈到了去年在 LPC 演讲中未能涉及的一个话题,即处理休眠持有者激活所需的复杂逻辑。当代理执行逻辑遍历阻塞链并发现锁的持有者正在休眠时,无法有效地捐赠时间使持有者运行。因此,调度器会将捐赠者出队(dequeue),然后将其添加到其等待的锁的持有者任务关联的一个列表中。当锁的持有者唤醒时,调度器可以将阻塞的捐赠者任务入队(enqueue)到同一个就绪队列上,以便开始代理。

然而,当涉及到 wait/wound mutexes 时,可能会发生“链中”(mid-chain)唤醒,这要求仅唤醒并入队那些正在等待该链中被 wounding 的互斥锁的任务。因此,我们必须维护一个完整的被阻塞任务的树形结构。还有一个额外的复杂性,由于这种关系是任务到任务的,受到 task->blocked_lock 的保护,并且我们需要获取 task->pi_lock 才能唤醒一个任务。锁的获取和释放特别复杂,需要在每一步中释放并重新获取所有的锁。更复杂的是,树中可能同时发生标准的解锁唤醒和多个链中唤醒。Stultz 建议,当提交这部分补丁时,他欢迎深入的评审和替代方法的建议。

Peter Zijlstra 提出观点,调度器可以只维护一个列表并唤醒其中找到的所有任务;这可能不是最优的,但希望这种情况在通常情况下很少发生。Steven Rostedt 也觉得这种更简单的方法很有吸引力。Stultz 表示犹豫,因为补丁的早期版本就使用了那种方法,但这导致了围绕 wait/wound mutexes 的许多 bug,而这些 bug 似乎在采用了更复杂的方法后消失了。但他表示会进一步评估。

Thomas Gleixner 指出, rt_mutex 的逻辑有类似的处理方式,应该参考。具体来说,他指的是该逻辑的文档编写方式,因为它也很复杂,试图将文档与代码内联(inline)会使代码变得混乱。Gleixner 建议,不如先在一个大的注释中全面解释清楚,然后使用编号的标注添加到具体的代码中。其他听众也认为这是记录复杂性的一种好方法。

随后,Stultz 转向了他 Android 系统团队遇到的其他一些杂项话题。

第一个话题是去年 OSPM 会议上 广泛讨论的 服务质量(quality-of-service, QoS)相关工作仍然很重要。他强调,Qais Yousef 的 QoS API 和 ramp-up multiplier 补丁 已显示为 Android 上的 Chrome 带来了不错的性能提升(5-15%)。事实上,当应用于未优化的 6.12 内核时,结果与已产品化、包含所有设备特定供应商钩子和启发式算法(heuristics)以改善调度行为的 6.1 内核上的表现相似。还需要进行更多评估来了解相对的功耗影响,但这似乎很有前景。

Dietmar Eggemann 提出观点,该系列补丁包含了相当多不同的改动,如果能将它们拆分开来,以便更好地理解哪些改动带来了收益,那会很不错。他之前也提到过这一点,Stultz 澄清说他尝试过拆分一些改动,但发现整个系列中存在依赖关系,使得这样做很困难。不过他认同了反馈,并请求大家在下次提交补丁时尽量帮助评审。

Stultz 讨论的另一个话题是 Android 越来越多地使用 任务冻结器(the freezer) 来限制后台任务。与代理执行类似,这是一种防止后台任务影响前台任务的解决方案,但其方式是在用户空间中冻结后台任务,使它们无法持有内核资源。任务冻结器常用于系统挂起/恢复(suspend/resume)和检查点/恢复(checkpoint/restore),但在 per-task(每个任务)的基础上使用较少。

这种方法显示出有前景的结果,但也存在副作用。这包括对冻结任务进行同步 Binder 调用(Binder call)而无法返回的问题。异步发送的 Binder 缓冲区必须保留,在接收方冻结期间无法释放。解决这些问题的努力正在进行中,但出现的另一个问题是与重复定时器(recurring timers)和看门狗定时器(watchdog timers)相关的问题。由于任务在冻结器中运行时无法执行,当它从冻结器中释放时,任何重复的应用程序定时器都会反复触发。这类似于早期在挂起和恢复中出现的问题,正是这个问题促使了在挂起时暂停 CLOCK_MONOTONIC 时钟 ID 的改动。类似地,看门狗定时器等可能在任务被冻结时触发,因此当任务唤醒时,可能会因为长时间不可运行而导致 panic。

因此,需要一个新的 per-task 时钟 ID,该 ID 在任务冻结期间不计算时间。Stultz 对这个想法有些犹豫,因为它尚未通用化,但他希望提出这个想法,以便大家了解这种任务冻结器的使用方式正在发生。人群中进行了一些讨论,认为也许可以使用时间命名空间(time namespaces),尽管这个想法似乎被否定了。Gleixner 强调,有一个时钟 ID 不会太糟糕,但定时器方面将很难管理。

他接着讨论的话题是实时音频(realtime audio)中遇到的 CPU 频率管理问题;他展示了来自 Pixel 6 设备上 Android 主线内核(mainline kernel)的一个 trace,其中一个实时任务改变了其 CPU 需求,但 CPU 频率变化不够快以避免 underruns(更奇怪的是,频率只有在任务迁移且 CPU 变为空闲后才增加)。Vincent Guittot 指出,对于主线内核,CPU 频率应该已经处于最高状态,尽管 android-mainline 没有启用调度器供应商钩子,Android 补丁中肯定存在一些其他逻辑导致了这个问题。

Zijlstra 询问为何没有使用截止时间调度。Stultz 澄清说,几年前曾尝试使用它,但未能成功;他不太清楚具体原因的背景。他同意进一步深入研究该问题,以了解 Android 在截止时间调度器方面遇到的问题,并更深入地研究 Android 补丁,看看在实时任务的频率缩放(frequency scaling)方面做了哪些工作。

最后,他建议在场的听众试用 Perfetto,它是一个出色的系统行为可视化工具。它的 trace(或 trace 的图像)可以成为描述问题或议题的有效速记方式,他认为这对社区非常有价值。与会者询问其功能与 KernelShark 有何不同;Stultz 解释说,虽然 Perfetto 提供的可视化功能(visualization)很有用,那部分与 KernelShark 类似,但 Perfetto 真正的强大之处在于它将 trace 导入数据库(database),然后你可以使用 SQL 进行查询,并将查询结果渲染为可视化。这使得很容易识别 trace 中问题发生的位置,并允许你为默认没有的指标(metrics)添加自己的可视化。他提到,大部分文档都专注于 Android 或 ChromeOS,但他创建了一份文档来展示如何在主线内核上使用它,并且真心希望大家花些时间试用一下,因为它在改善社区沟通方面具有很大潜力。

通过更好的利用率信号改进能源感知调度

演讲者:Pierre Gondois (视频)。

利用率信号(Utilization signals)用于告诉调度器特定任务需要多少 CPU 时间,但它们受到任务共享同一就绪队列(run queue)的影响。在这种情况下,测得的利用率不一定代表任务的实际大小;它代表调度器 赋予 了该任务多少时间。特别是,如果任务 A 和任务 B 在同一个队列中,当任务 B 运行时,任务 A 会被视为空闲。

在一个完全利用的 CPU 上,任务的 util_avg 值代表了对任务实际大小的低估。任务的 util_avg 受任务相对 nice 值(nice value)的限制。一个 nice 值较低的任务会获得更多的运行时间,并且看起来比 nice 值较高的任务“更大”。

为了解决这个问题,创建了一个原型信号 util_burst 。该信号累计任务在入队(enqueued)期间运行的时间量,然后在出队(dequeuing)时一次性计算其贡献。这使得共同调度的任务在另一个任务被调度时不会被视为空闲。在一个完全利用的 CPU 上,任务的 util_burst 信号不受该任务相对于底层 CPU 的 nice 值限制;它会慢慢增长直到达到最大值 1024。

这种对任务大小的估计与 UCLAMP_MAX 特性相关。 UCLAMP_MAX 旨在将 CPU 置于完全利用状态。这会扭曲对 UCLAMP_MAX 任务大小的估计,导致任务放置不准确。

实际上, UCLAMP_MAX 任务现在由能源感知调度器(EAS, energy-aware scheduler)进行放置,它使用利用率值来放置任务。在完全利用的 CPU 上,负载应该在 CPU 之间平衡,并且应该忽略利用率。因此,在这种情况下应该使用负载均衡器(load balancer),或者不应该通过 EAS 调度 UCLAMP_MAX 任务。

重新思考 overutilized — 何时退出 EAS?

演讲者:Christian Loehle (视频).

Linux 调度器的能源感知调度(EAS)模式基于 per-entity load tracking (PELT) 利用率信号,做出每任务的 per-CPU 位置决策,以便将任务放置并打包到最节能的 CPU 上。很显然,这并非总是可取的,因此,当一个运行队列(run queue)的利用率超过 CPU 容量(capacity)的 80% 时,EAS 会自动停用,并回退到传统的容量感知负载均衡(load balancing)模式。这样做的动机是,当计算需求未能满足时,利用率数据不再可信,而且在这种情况下,潜在的节能效果也微乎其微。

然而,这个机制正显现出过时迹象。80% 的阈值(threshold)是静态的,不依赖于 CPU 类型,也对工作负载(workload)行为无感。在现代异构系统(heterogeneous systems)上,尤其是在具有复杂核心拓扑(core topologies)的移动 SoC(System on a Chip,片上系统)或拥有许多大核的笔记本电脑上,这导致系统频繁地从 EAS 中退出。这些转换通常由短暂的峰值触发,这些峰值并未反映持续的需求,但全局的 overutilized 状态 nonetheless 会影响整个系统。

在 Pixel 6 上,该设备具有 little、mid-size 和 big 核心的集群,little 核心的容量为 160(标准化后的容量为 1024),在适度的工作负载下,它们经常会超过 overutilization 阈值。由于 80% 的阈值在这些 CPU 上仅相当于 128 的容量,一个短暂的升高就足以停用 EAS,即使此时 big 核心处于空闲(idle)且可用状态。这会导致任务从 little 核心迁移(migration)到 mid-size 或 big 核心,然后在需求下降后又迁移回来,形成一个不稳定的放置循环,从而破坏了节能效果。

在桌面级硬件上,例如 Apple M1 的变种,它们拥有比 little 核心更多的 big 核心,问题表现有所不同。单个计算密集型线程在一个 big 核心上运行,就可以使其超过阈值,从而在整个系统中停用 EAS。对于传统上只有不超过两个 big CPU(且无法同时保持散热稳定)的移动 SoC 来说,这是可以接受且罕见的;但对于笔记本电脑的使用场景,这一点可以改进。

关于 overutilization 的根本问题在于,当计算需求超过所提供的计算容量时,调度器无法信任 PELT 的 util_avg (及其衍生值)。如果一个任务被放置在一个算力不足的 CPU 上并被限制(throttled),则该任务的负载会被高估。

讨论了几种解决这些问题的方案。一种方案是像 Yousef 建议的那样,使 overutilization 阈值动态化。阈值不再是硬编码的 80%,而是会考虑一个任务如果持续运行直到下一个时钟周期(tick),可以累积多少利用率。这样可以考虑 160 容量的 little 核心与 1024 容量的 big 核心之间的差异。虽然这引入了有用的拓扑感知能力,但它有可能对 little 核心产生反作用,减少它们的安全运行余量(headroom),从而可能在正常突发(bursts)情况下更早地触发 overutilized 状态。

一个更保守的方法是引入一个延迟期(linger period),然后再设置或清除 overutilized 标志。由于大多数 overutilization 事件都是短暂的,通常持续不到 1 毫秒,延迟状态转换可以过滤掉噪音。实验结果表明,在清除标志之前引入一个时钟周期(tick)的延迟,可以将 overutilized 事件减少近一个数量级,而总体上并未显著增加处于 overutilized 状态的时间。这可以在对响应性(responsiveness)产生最小副作用的情况下,提高 EAS 的稳定性。

具体来说,对于笔记本电脑中常见的拓扑结构,如果一个 big CPU 由于单个任务而被标记为 overutilized,可以将该核心排除在全局 overutilized 评估之外,因为 PELT 信号的可信度并未受到影响,且该任务的最大吞吐量(throughput)已经得到保证。虽然这个想法在移动 SoC 上的价值有限,但在桌面和笔记本电脑上变得相关,因为在这些平台上,单个任务占据主导地位的情况更为常见,并且性能预算受散热设计(thermal design)的约束较少。

一个更激进的想法是完全重新定义 overutilized 的条件,不再基于利用率指标,而是基于观察到的空闲时间(idle time)来做决定。如果一个 CPU 在最近的一个窗口期内没有空闲过,例如 32 毫秒(当前 PELT 的半衰期,PELT-half life),则可以假定其处于 overutilized 状态。这种方法更直接地反映了实际的计算需求。

出现了两个问题。这种方法不再与 DVFS(动态电压频率调整)无关,这意味着缓慢的 DVFS 反应或临时的 DVFS 限制可能会触发 overutilized 状态。更大的问题是,这与 UCLAMP_MAX 不兼容,因为只要 UCLAMP_MAX 实际生效,条件就应该被满足(因为提供的计算容量被人为限制了)。

这里存在一个更深层的问题。=UCLAMP_MAX= 的存在(在 Android 上用于限制任务利用率估计以节省能源),破坏了任何依赖于利用率或空闲时间推断(idle inference)的机制。一个任务可能以 CPU 容量的 50% 运行,并非因为需求有限,而是因为它受到了用户空间策略(user-space policy)的约束。在这种情况下,其利用率数据实际上是无效的(garbage)。更糟糕的是,在该 CPU 上调度的任何额外任务都会污染其自身的利用率信号。因此, UCLAMP_MAX 的存在限制了替代性 overutilization 定义的设计空间。

一种潜在的解决方案是将 UCLAMP_MAX 重新定义为对 util_avg 的硬上限(hard cap),一旦任务达到其最大值,就通过阻塞或将其调度出(scheduling out)来有效限制该任务。这将使 PELT 再次变得可信,但代价是改变 UCLAMP_MAX 的语义(semantics),这可能对现有用户来说是不可接受的。目前尚不清楚这是否可行,特别是考虑到 Android 供应商通过定制的供应商钩子(vendor hook)实现如何严重依赖这些接口。

结论很明确:当前的 overutilized 机制在现代拓扑结构或不同的使用场景下扩展性不佳。它依赖于一个单一的全局阈值,并且与 UCLAMP_MAX 的纠缠,都导致了跨平台的异常行为。尽管之前讨论过一些方法,但迄今为止没有任何提案取得进展。

讨论围绕着已经提出的方案、PELT 信号的局限性,但也包括 UCLAMP_MAX 的问题,更具体地说,是关于那些没有明显的主线(mainline)用户(而是通过修改功能间接的下游用户)的用户空间策略,以及这些策略应该在多大程度上限制围绕 overutilized 状态的未来发展。

如何验证 EAS 和 uclamp 的功能?

演讲者:Dietmar Eggemann (视频).

本次演讲讨论了邮件列表上一些 EAS 和 uclamp 补丁集(patch sets)缺乏评审的问题。Android 的高商业利益、碎片化的测试环境以及供应商特定的定制(customizations)在一段时间内阻碍了该领域的协作。传统的性能基准测试(benchmarks)不足以应对,因为 EAS 和 uclamp 的目标是平衡性能和能源效率。相反,提到了工作负载生成器 rt-app 、ftrace 和 EAS/PELT 内核跟踪(tracing)作为此工作的工具。

一个提议的解决方案是分享能触发补丁引入的行为变化的 rt-app 配置文件,以及如何将其适配到不同硬件(例如,CPU 数量、容量、任务参数)的说明。这可以在各种异构(heterogeneous)平台上实现一致的测试,同时保持数据分析的灵活性。

Arm 已经为 uclamp sum aggregation 补丁系列采用了这种方法,使用了 JupyterLabs notebook 和 LISA (Linux Integrated System Analysis) 工具包。对我们所有人来说,应该清楚的是,仅依靠 Android 发布周期中的测试是不够的,并且存在将回归(regressions)引入主线(mainline)EAS/uclamp 代码的风险。

让用户空间感知当前的 deadline 调度器参数

演讲者:Tommaso Cucinotta (视频).

SCHED_DEADLINE 调度器允许通过 sched_getattr() 系统调用读取其静态配置的 run-time、deadline 和 period 参数。然而,目前没有直接的方法从用户空间访问调度器内部使用的当前参数:即瞬时(instantaneous)的 run time,以及当前的绝对 deadline(absolute deadline)。这些信息可以告诉一个任务在当前的计算周期(computation cycle)内还有多少可用的 CPU 时间。

演讲描述了在自适应实时(realtime)应用程序(adaptive realtime applications)中使用这些数据的必要性,并提出了两个用例(use cases)。第一个用例涉及不精确计算(imprecise computations),这在控制应用程序(control applications)中非常常见,实时任务在执行完其最重要的计算后,如果直到 deadline 还有足够的剩余 run time 可用,它可能会决定执行一个可选计算(optional computation)来细化其输出。第二个用例涉及一个 SCHED_DEADLINE 线程(threads)池(pool),该线程池从共享队列(shared queue)中处理作业(jobs),其中每个线程需要精确了解其自身的剩余 run time 和绝对 deadline,以便估计是否可以选取并处理一个新的作业。

演讲比较了几种读取当前 SCHED_DEADLINE 参数的方法。

  • 使用用户空间启发法(heuristics),这存在“开环”(open-loop)测量的风险,可能与内核使用的真实值不同步(out-of-sync)。

  • 使用通过 /proc/self/task/pid/tid/sched 特殊文件(special file)暴露的值,该文件包含 SCHED_DEADLINE 任务的 dl.runtime 和 dl.deadline 行。这种方法效率低下,因为需要在内核空间中将数字格式化为十进制表示法(decimal notation),并在用户空间中重新解析(parse)它们。这种方法还存在一个问题,即在用户空间中正确解释 rqclock 引用中可用的绝对 deadline 信息。

  • 使用一个内核模块(kernel module),通过 /dev/dlparams 特殊设备(special device)以二进制格式(binary format)更高效地暴露所需的数字。然而,该模块无法直接访问 deadline 调度器 API(Application Programming Interface,应用程序接口) 来更新剩余的 run time,因此它可能会为此目的调用 schedule(),考虑到实际需求,这可能有些过度(overkill)。此外,如果参数是从与被监控的 SCHED_DEADLINE 任务运行的 CPU 不同的 CPU 上读取,这种方法也无法工作。

最后,演讲提出了一个对 sched_getattr() 的小内核补丁(kernel patch);它使用 flags 参数(目前要求包含零)来使进程能够请求其剩余的 run time 和绝对 deadline(转换为 CLOCK_MONOTONIC 引用),而不是静态配置的参数。

向 OSPM 听众提出的问题包括:

  • 用户空间接口的适用性,特别是向 sched_getattr() 添加一个标志;在这方面,反馈似乎是积极的。

  • 除了相对于 CLOCK_MONOTONIC 返回当前绝对 deadline 外,是否可以选择相对于 CLOCK_REALTIME 返回:添加此选项似乎价值不大,因为任何实时应用程序都应该设计为不依赖于 CLOCK_REALTIME 。

  • 如果在同一 deadline 周期内进行多次调用,返回的绝对 deadline 值可能表现出一些纳秒级的变异性(variability)。

  • 读取当前参数可能导致耗尽其 run time 的 SCHED_DEADLINE 任务立即被限制(throttled)。如果没有这样的调用,在默认内核配置下,限制会发生在下一个时钟周期(tick)。考虑到合理使用 SCHED_DEADLINE 需要启用 HRTICK_DL 调度器特性(feature),在这种条件下不会有这样的行为差异,所以这似乎不是一个大问题。

  • sched_getattr()

     在调用 update_rq_clock() 和 update_curr_dl() 时会获取被监控的 SCHED_DEADLINE 任务所在的运行队列的 rq->__lock ,当执行系统调用的任务在不同的 CPU 上运行时,这是否会构成问题。

EEVDF 验证器:追赶进度的故事

演讲者:Dhaval Giani (视频)

演讲以对参与听众承诺提供(瑞士)巧克力开始。Giani 首先谈了谈 EEVDF 技术报告,该报告指导了内核 EEVDF 调度器的实现。他指出,这是 CPU 调度器的 SCHED_NORMAL 类别首次基于一篇学术论文,它带来了一些有趣的想法,其中最主要的是围绕着调度器功能测试(functional tests)的概念。长期以来,调度器都是围绕着一个核心算法的一系列启发法(heuristics)。

他首先通过一个简单的例子讲解了 EEVDF 算法——展示了 lag、deadline 和虚拟时间(virtual time)是如何计算的。基于此背景,讨论了该算法提供的数学保证(mathematical guarantees)。这些保证将构成 EEVDF 功能测试的基础。当被问到时,Zijlstra 同意这是对论文的充分解释,可以作为未来讨论的基础。

接着,焦点转移到 Linux 实现与论文的不同之处。其中一个主要变化源于 EEVDF 未考虑 SMP(Symmetric Multiprocessing,对称多处理),而 Linux 在 1996 年引入了对 SMP 的支持,技术报告则于 1995 年发布。另一个主要区别是控制组(control groups)存在层级结构(hierarchy)。由于这些原因,不可能存在论文所依赖的全局虚拟时钟(global virtual clock)。相反,对于每个调度器的运行队列,都有一个“零延迟”(zero-lag)的 vruntime 值,用于跟踪 CFS(Completely Fair Scheduler,完全公平调度器)运行队列的虚拟时钟位置。Linux 实现还利用了一些数学特性来限制(clamp down)lag,以减少数值不稳定性(numerical instability),这算是做了一些变通。

接下来,Giani 谈到如何利用论文中引入的引理(lemmas)和定理(theorems)预期的结果来测试算法是否仍然忠实于论文,如果不是,则记录引入的差异。涵盖了两个测试用例(test cases),大家一致认为它们有意义,即使它们总是会通过。如前所述,这是在测试功能性——其中任何一个失败都意味着底层发生了根本性改变。

Zijlstra 建议,出于测试目的,可以放宽一些限制(clamps),以观察 vruntime 更新相关的数学计算有多不稳定。这也将有助于记录在哪些情况下需要进行限制。

至于如何触发这些测试尚待决定,但它们需要作为内核的一部分实现,因为它们深入调度器内部(scheduler internals),并且不希望将这些内部细节暴露在调度器之外。

演讲结束时,Giani 指出他已完成开发的两个测试在当前实现上运行良好,祝贺了 Zijlstra,并为他的辛勤工作提供了额外的巧克力。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值