本文主要是介绍LWN:Latency nice的方方面面!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
关注了就能看到更多这么棒的文章哦~
The many faces of Latency nice
作者:Jonathan Corbet
2020年5月18日,OSPM会议
原文来自:https://lwn.net/Articles/820659/
主译:DeepL
task(任务,意指进程)的 "nice"值规定了它在completely fair scheduler(CFS)中的优先级。它的语义起源于古老的Unix传统。去年8月,有人提出了一个 "latency nice "参数,可以用来对task的响应时间需求进行类似处理。在 2020 年的 Power Management and Scheduling in the Linux Kernel Summit(OSPM)上,Parth Shah、Chris Hyser 和 Dietmar Eggemann 关于latency nice 的提议进行了一次讨论;似乎大家都同意这会是一个很有用的功能,但对于它究竟应该做什么,大家的意见不一。
A different kind of nice
Shah首先描述了一下什么是latency nice value,这是一个per-task的属性,行为上很像普通的nice值。它告诉scheduler(调度器)这个task的latency需求。这个latency nice值可以通过sched_setattr()系统调用来调整,不过有些人希望切换到cgroup接口。它的值在-20和19之间变化(和nice一样),-20表示对latency非常敏感,19表示对latency完全无所谓。默认值为0。
他提出的第一个问题与权限有关:是否允许一个没有特权的进程降低其latency nice值?当然,普通的nice在这种情况下是不允许修改的,进程必须有CAP_SYS_NICE能力来降低其nice值。为latency nice设立类似规则的话,就能阻止潜在的拒绝服务(denial-of-service)问题,但代价是普通用户就无法利用这个提升latency响应情况的功能了。
是否只允许特权用户调用,这应该取决于它做了些什么事情,但这一点还没有讨论过。起初,这个功能是用来控制scheduler在唤醒某个进程时,愿意花多大努力寻找一个空闲的CPU来执行这个task。这种寻找过程需要时间(从而增加了latency)。而idle的CPU可能还需要从睡眠状态中唤醒,进一步增加了latency。Dhaval Giani指出了一个Oracle关心的用例,在这个用例中,一些对latency敏感的task通常会只执行非常短的时间,有时比搜索空闲核心所花费的时间还少。通过设置一个低latency nice值就可以避免这个搜索动作,从而减少耗时。
Giani还提到了一个来自Facebook的用例,Facebook希望让运行时间较长的task能尽快全速运行起来,所以Facebook在希望能得到低延迟的同时,也希望能找到一个能快速完成大量工作的空闲CPU,就能更好地满足其需求。而IBM则希望通过这个设置来控制scheduler,避免将task放在目前正在执行对latency很敏感的的CPU上。关于用例的讨论到这一点就中断了,人们承诺稍后会重新讨论这个问题。
回到权限问题上,Qais Youssef建议暂时只允许特权用户来降低latency值,特别是考虑到这个设置将来可能会有新的含义。Shah说,对于目前的用例来说,似乎不存在任何denial-of-service的问题。
Eggemann想知道取值范围是多少。既有人希望增加latency nice值,也有人希望减少,但目前还不清楚一个正数的latency nice值的实际效果会是什么。Patrick Bellasi建议,我们计算出的一个进程可以执行多长时间才会被别人抢占(prempt),这个时长就可以用latency nice值来相应地放大缩小。Vincent Guittot说,普通的nice值,每增加1,就会对进程可能使用的CPU时间就带来10%左右的差异。他说,对于latency nice来说,-19、0和+20的值是有意义的,但他讲不清楚其他这些中间值意味着什么。Hyser说,对于负值,可能会在决定task放置在哪个CPU上的时候要搜索的CPU数量有直接的影响。Shah建议,正值可以允许在系统中的任何CPU放置task,哪怕是那些连Cache都没有共享的CPU(通常来说这种情况下scheduler会极力避免,因为cache利用率下降了)。
Eggemann随后表达了一个在会议中会听到许多次的感慨:latency nice是试图用一个值来控制太多东西的功能。Bellasi建议,可以在review patch时总结出各种使用场景,并询问是否用法与语义有明确矛盾的情况。Giani就提醒上面提到的Oracle和Facebook的用例就是矛盾的。
Control groups
Eggemann在这时接管了演讲,谈了一下Android开发者的需求。Android目前使用了一个cgroup接口,其中包含了一个 "prefer idle"属性;设置这个属性的话就会在选择CPU时优先挑选空闲的CPU。不过,这个设置的真正作用是绕过了一些energy-aware scheduling的代码逻辑,这部分代码本身就会引入一定的latency。因此,在这种情况下,那些对latency敏感的task会尽量寻找空闲的CPU来执行,这恰恰与上面描述的情况相反。
不过,他真正目的是希望讨论出一个潜在的基于cgroup的latency nice接口。cgroup是一种分配进程用到哪些资源的机制,正好适合目前的需求。利用CPU controller,有三个方面来影响CPU资源的分配。其中,"weight"值给当前group设置了相对优先级,而 "max"值则限制了可用的最大CPU时间,"min"值则确保最少能拿到的CPU时间。最大最小utilization(利用率)也进行了控制。
在这个情况下,latency nice该如何管理?他说,所控制的资源实际上仍然是CPU cycle数。但latency需求和CPU cycle之间的关联性并不像上面描述的参数那样明确。他不确定什么样的语义会被cgroup维护者所接受。Bellasi建议采用一个分段设置,每个cgroup都有数字来设置该组中的task可以请求的最小和最大latency值。但是,Guittot指出,对latency值的更改必须向上传播到cgroup各个层级的根(root)位置。讨论在这一点上纠缠了好一阵子,最后人们决定继续专注在latency nice值该如何起作用这一点上继续讨论。
Eggemann最终建议先讨论后面的吧。他说,也许每次用例刚一提出来的时候就应该讨论一下。他说,cgroup接口对Android来说才是真正重要的,所以也许最好先搞清楚per-task的属性都是怎么实现的。
Use cases at last
Hyser这时接下来继续讨论使用场景。他重申,这组patch set的初衷是为了跳过搜索idle cpu过程对latency敏感task的影响。这个改动在transaction-processing benchmark场景中性能提高了1%。很多workload的关键进程不会运行很长时间,但需要在它想执行时能马上得到运行。通过调整latency nice值,可以让许多这样的workload不需要使用realtime patch。
他贴出了一些图表,可以看出latency nice确实能带来更小的延迟。在CPU数较多的系统上效果更明显。
他建议将负值理解为要搜索的CPU core数目,-20的值表示完全不搜索CPU core,-19就会搜索一个CPU core等等。但这个值是否应该按照系统中的CPU数量来换算成比例?目前还不清楚应该如何解释。他建议说,在实际使用中,latency nice看起来很像一个布尔值:要么搜索其他CPU core来放置task,要么干脆不搜索。
Giani 说,改变task的 nice 值的效果很好理解;而改变latency nice 的效果则相对难于理解。Hyser建议,可以看做是调整对latency敏感task的schedule domain size。但是schedule domain是依赖于硬件的,这使得我们很难提出一个与硬件无关的latency nice值的描述。Hyser说,-20的值,完全不搜索CPU core,至少这个值是不依赖于硬件的。他最后说,-1的值可能可以定义成会进行CPU搜寻,但是会关闭energy-aware scheduling。
Giani说,latency nice似乎想处理很多事情,他想知道用一个接口来控制这一切是否合理。Peter Zijlstra回应说,至少这些东西都会影响latency。Rafael Wysocki说,仅有一个整数值不足以代表这所有一切。Zijlstra说,这次会议确实应该从使用场景开始讨论,然后再看一下可以调整哪些内容,从而来满足这些用例的需求。
Shah讨论了task-packing这个使用场景。在采用英特尔 "turbo" mode的系统上,如果把多个task打包到少数的CPU core上,就可以节省出许多的资源,让其他CPU core进入turbo模式。他建议,可以尽量把latency nice值大于15的task都尽量pack起来,只要能保证目标CPU上的占用率不会超过阈值就好。在他测试的一个workload中,这样做会带来14%的性能优势。
另一个用例是限制CPU可以进入的睡眠状态。pm_qos机制现在可以做到这一点,但它是一个系统范围内的参数,没有对每个task进行控制,因此在大型系统中的应用效果并不理想;它没有latency敏感task的运行位置的概念。他建议实现一个per-CPU计数器,标示有多少个latency sensitive task。如果某个CPU正在运行这样的task,就可以相应地禁止它进入某些睡眠状态。
Wysocki回应说,这不是一个现实中合理的需求。比如说,如果task被迁移走了,情况就会很乱。对于这种情况,latency nice并不是一个很好的接口。没有办法将latency nice的值和可以容忍多长的CPU exit latency对应起来。他认为用这种方式捆绑语义是行不通的,这样的接口需要用户通过在特定平台上的不断实验来确定自己的latency nice值。
不过Shah坚持他的想法,比如让具有latency sensitive task的CPU不要进入idle,这可能是有好处的做法。scheduler benchmark测试结果可以看出,在保持类似功耗消耗的情况下,采取了这种措施后能看到latency显著降低。pgbench的运行结果也显示出latency有很大改善,但代价是功耗更高(有时高了许多)。
Youssef说,能实现这一切功能的接口,就是我们目前的核心目标。Thomas Gleixner表示同意,他说-20...19范围值,"需要一个水晶球 "来帮我们占卜才能用起来。Zijlstra再次呼吁,在进入接口细节讨论之前,还是要先列举完整所有应用场景。Giani重复说,现在的接口看起来并不好,并且他同意需要更全面地研究那些用例。他说,目前的工作顺序反了。
Eggemann最后说,大家需要收集用例并 “take them all seriously”。虽然讨论围绕着这些要点继续讨论了一段时间,单有实际内容的讨论就到此为止了。
关于更多的图文和其他细节,请参见本次会议的ppt。
全文完
LWN文章遵循CC BY-SA 4.0许可协议。
欢迎分享、转载及基于现有协议再创作~
长按下面二维码关注,关注LWN深度文章以及开源社区的各种新近言论~
这篇关于LWN:Latency nice的方方面面!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!