LWN:在x86上实现跟当前频率无关的占用率分析!

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

Frequency-invariant utilization tracking for x86

By Jonathan Corbet
April 2, 2020

原文来自:https://lwn.net/Articles/816388/

主译:DeepL

内核提供了许多CPU变频策略(称之为governor)供用户选择;按照大多数人的说法,其中最有效的是 "schedutil",它在2016年合入了4.7内核。不过schedutil是在移动设备上使用的,它在x86台式机上仍然没有太多用处。intel_pstate governor通常被人们认为是在x86处理器上能给出更好的结果,因为这个governor设计中参考了一些秘密信息。但是,最近合并到5.7的一组补丁让schedutil更好地了解了x86处理器的真实利用率,从而大大提高了这个governor方案的有效性。

合理选择CPU频率非常重要,原因如下:如果将CPU的频率设置得太高,那么会引入不必要的额外功耗,无论CPU是在手机中还是在数据中心里运行,功耗问题都会引起关注。相反,如果将频率设置得太低,则会损害系统的性能;在最坏的情况下,可能会导致当前CPU能力不足以满足workload的需求,甚至因为它使系统一些部件长期无法进入睡眠状态,反而会增加功耗。因此,人们非常有动力去改进这里的决策机制。

任何一个CPU频率的决策算法,都需要依赖一个关键的输入信息:此CPU的负载。一个高负载的处理器自然要比一个几乎处于空闲状态的处理器更加需要运行在高CPU频率。"负载(Load)"一般通过CPU实际运行此workload的时间百分比;一个持续运行的CPU就算作是100%的负载。不过,有一个小细节需要考虑:CPU的当前工作频率。一个CPU可能100%的时间都在运行,但如果它的工作频率是最高频率的50%,那么它实际上并不是100%的负载。为了处理这个问题,内核的load tracking机制会根据CPU的运行频率对所观察到的负载进行折算;这个折算后的值才会用来确定CPU的真正负载是多少,以及它的频率应该如何变化。

在某些处理器上已经是这样做的。不过在x86处理器上,这种根据CPU频率折算来进行load tracking的机制一直没有用起来。这意味着像schedutil这样的frequency governor无法做出最佳决策。不出预料,性能(以功耗和CPU吞吐量来衡量)一定不会是最优的。

这似乎是一个明显的很容易修复的问题。但是问题的症结在于,在当代的Intel处理器上,实际上无法知道CPU的工作频率。操作系统对CPU的运行功率点有一定的控制权,可以提出一些礼貌性的建议,但像真正运行的频率这样的信息都是在处理器内部自己决定的,内核没有这方面的信息,也就不需要担心这类问题。但是没有这些信息的话,就不可能得到x86处理器的真实利用率。

不过,其实还是有一种方法可以近似估算这些信息。早在2016年,Len Brown就提出了这个方法,但当时并没有被采纳。现代x86处理器上有两个model-specific(跟具体型号有关的)寄存器(MSRs),称为APERF和MPERF。这两个都可以被认为是一种时间戳计数器,随着CPU的执行而递增(虽然Intel强调这些寄存器的内容不可以真正用来进行计时)。MPERF以与处理器最大频率成比例的恒定速率递增,而APERF则以与实际工作频率成比例的可变速率递增。如果aperf_change是APERF在某一时间段内的变化,而mperf_change是MPERF在同一时间段内的变化,那么工作频率可以近似地表示为

    operating_freq = (max_freq*aperf_change)/mperf_change

读取这些MSR是相对比较耗时的操作,所以不能经常进行这样的计算,但每一个clock tick(每1-10ms)进行一次就足够了。

不过还有一个小细节,就是Intel的 "turbo mode"。老一辈的人一定会想到当初PC机箱上的按钮,可以让CPU以惊人的6MHz频率运行,但这个turbo mode其实是不一样的。当一颗处理器芯片内部只有少数几个CPU在工作,而其他的CPU都是空闲的时候,这些繁忙CPU可以运行在高于规定的最高频率以上。这就使得我们很难知道一个CPU的真实利用率是多少,因为这个CPU的可用计算力,会根据系统中其他CPU的工作情况而变化。

这个patch set(由Giovanni Gherdovich提出)实现了上述的计算工作频率的方法,并且定义了最高频率为其中四个处理器同时能达到的turbo频率。这样就提供了一个合理的衡量某个处理器利用率的方法。这样schedutil就能够更好地决定每个CPU的工作频率到底应该是多少。

此外,当 schedutil 知道它所得到的利用率数字是经过CPU频率折算过的绝对值的时候,它选择频率的算法就会也发生一些变化。在没有这个绝对指标的时候,schedutil只能将频率一步步向上或向下变化。有了这个绝对指标之后,它可以更好地计算出频率应该是什么,所以它可以进行跳过多个频率一次调整到位。这样,它就可以尽快地调整频率来适应当前的真实workload。

Gherdovich在补丁更新日志中评论了这组patch的最终效果,他说schedutil的性能 "即使不能与intel_pstate驱动/框架中的power-supervisor governor提供相同结果,也是非常接近的"。为了证明这一点,changelog中包含了一长串benchmark结果,所以changelog比补丁本身还要长。虽然这些测试结果并不全都是正面的,但能看出有巨大的改进(在性能和功耗方面),而变差的数据一般都是一些特定场景的测试中,并且只变差一点。。好处最大的工作场景之一是编译内核,这个结果基本上保证了kernel开发者们不会因此而反对这个改动。

感兴趣的读者可以阅读patch changelog中的benchmark的完整结果。对于我们其他人来说,最重要的是看到schedutil CPU-frequency governor 在 x86 机器上的表现应该比过去好得多。是否会引发一些发行版也切换到schedutil呢?这还有待观察;这将取决于它在实际workload上的表现如何,而实际workload通常并不会像benchmark有那么好的结果。

全文完

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

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

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

你可能感兴趣的:(LWN:在x86上实现跟当前频率无关的占用率分析!)