2014年Linux内核峰会(Linux Kernel Summit 2014)上举办了为期一天的EAS主题研讨会。来自Arm的Morten Rasmussen做会议主持,来自Linaro的Daniel Lezcano和Mike Turquette介绍了最近发布的EAS相关工具,从此EAS开始快速发展并被人所知,智能设备的厂商们争先恐后地学着应用此技术。
节约能源的观念我们并不陌生,可是让内核学会自己节约能源却是一件新鲜的事情,谷歌在2017年发布的Google Pixel 2就具备这一技术。EAS不仅让Google Pixel 2功耗降低,还可以更快?快来看看这是怎么回事。
-
“core” 一词在CPU相关文章中经常翻译为“内核”,但是在本文中翻译为“核”,以区别软件的内核“kernel”。
-
big.LITTLE是由ARM公司于2011年提出的基于异构计算的CPU架构。在这个架构中,分为相对较耗电但运算能力强的核所组成的大核“big”,和相对耗电低但运算能力弱的核组成的小核“LITTLE”,这些核共享存储器区段, 因此可以在大核和小核之间即时交换工作负载。采用big.LITTLE架构的CPU,可以同时拥有强大计算能力和节能的特点, 一般运用在移动设备上。
-
OnePlus 3是一加手机第三代旗舰机,搭配高通骁龙820 处理器;2016.06.15 上市。OnePlus 3T搭配高通骁龙821处理器;OnePlus 6搭配高通骁龙845 处理器, 2018.05.18上市。本文发表于2018.6.30,主要对比分析了当时一加的最新产品OnePlus 6和Google最新产品Pixel 2 对EAS技术的应用情况。
原文链接
https://www.xda-developers.com/google-pixel-fastest-android-phone-eas/
这对您的下一款智能手机意味着什么
当Linux还只是Linus Torvalds头脑中的一个想法时,那个年代只有单核CPU,这些CPU的功耗很小。第一个商用处理器Intel 4004在单核上以740kHz的频率运行。那时还不需要使用负载调度器(load scheduler)。负载调度器的出现是为数十年之后出现的IBM Power 4等双核“庞然大物”准备的。它们运行在惊人的1.1GHz到1.9GHz之间,并且需要程序和系统的支持才能正确运行多核。我们如何让这些机器硬件(即多核CPU)使用多核的软件算法?您可能以前在我们的论坛上听说过功耗感知调度(EAS)。这是Google Pixel智能手机表现如此出色的部分原因。EAS到底是有什么了不起,以及我们如何应用它?在解释之前,我们需要讨论Linux调度器。
Linux调度器的演变
轮转调度
轮转(round robin)是一个容易解释也容易理解的概念,而且也不难理解其缺点。轮转使用时间片为每个进程分配时间。假设我们的计算机上正在运行四个进程。
-
进程A
-
进程B
-
进程C
-
进程D
现在,让我们描述轮转调度器的工作。在继续进行下一步之前,我们将为每个进程分配100毫秒(时间片)。这意味着进程A先执行100毫秒,然后轮到进程B执行,依此类推。如果应用程序的工作需要250毫秒才能完成,则仅需完成3次此过程即可完成工作!现在,将以上方法扩展到多核,以便将进程A和进程B分配给核1,将进程C和进程D分配给核2。这种方法被O(n)调度取代(O(n)调度类似于轮转调度,但是新增了 epoch ,并允许动态分配时间),然后产生了O(1)调度(O(1)调度让开销最小化,且支持无限制的进程),最后产生了完全公平调度器(CFS)。CFS于2007年10月合并到Linux内核版本2.6.23中。
完全公平调度器
完全公平调度器自诞生以来就用在Android中,并且在非big.LITTLE设备上使用。它使用一种智能算法来确定处理顺序,时间分配等。这是经过精心研究被称为“加权公平排队”调度算法的应用实例。CFS主要为机器上运行的系统进程和其他高优先级的进程提供优先权。如果要在big.LITTLE设备上运行,则所有核将被视为平等。这很不好,因为低功耗核可能被迫运行密集的应用程序,或者更糟的是发生相反的情况(译者注:即一段时间内高功耗核运行的应用程序非常少,对高功耗核是一种浪费)。例如,听音乐的解码过程也许会在大核上执行,这就造成了不必要的功耗增加。这就是我们需要为big.LITTLE设备使用新调度器的原因,新调度器才能够以节能方式识别和利用核差异。这就是异构多处理(HMP)的出现,它是大多数Android手机现在正在运行的标准调度器。
异构多处理
这是近年来发布的任何big.LITTLE设备(Google Pixel除外)的标准调度器。HMP利用big.LITTLE架构,将低优先级且不那么繁重的工作委派给消耗更少功率的小核。HMP是“安全的”,即不会犯错误的,它知道哪些任务应该去大核,哪些应该去小核。它确实可以工作,并且相比EAS在开发方面所需的精力更少。(EAS会在下文详细介绍。) HMP只是CFS的扩展,以使其具有功耗意识。
HMP不会猜测,即不会预测未来的进程。这没毛病但这就是为什么HMP设备不能像运行EAS的设备那么流畅的原因,也是为什么它会更耗电的原因。最后,HMP的不足使我们迎来了功耗感知调度(EAS),我坚信未来随着更多OEM的采用,EAS将应用于ROM和内核开发。
功耗感知调度
功耗感知调度(EAS)是我们论坛用户谈论的下一件大事。如果您正在使用OnePlus 3(或Google Pixel),您肯定在论坛上听说过OnePlus。最新的OnePlus 6搭配高通骁龙 845进入主流发布,因此,如果您拥有这些设备之一,那么您已经拥有支持EAS的智能手机。诸如RenderZenith之类的内核形式的EAS 和诸如VertexOS和PureFusion之类的ROM 席卷了OnePlus 3论坛。当然,Google Pixel也附带EAS。承诺延长电池寿命并提高性能,还有什么猫腻呢?
功耗感知调度并非如此简单,并不是CFS或HMP之类的每种设备都通用的。EAS要求我们基于功耗模型理解正在运行的处理器。这些功耗模型是由工程师团队不断测试并努力提供最佳性能而建立的。由于骁龙820和821基本相同,因此OnePlus 3上定制的内核使用Google Pixel功耗模型。配备骁龙845的设备可以使用EAS,因此OnePlus 6可以在某种程度上使用EAS 。虽然它不像Google Pixel设备在调整参数方面做的那么好,但它也完成了这项工作。这是一个示例,尽管OnePlus 6在EAS方面拥有更好的处理器,但Pixel 2 XL在平滑度上仍胜过OnePlus 6。这两个图像均来自我们OnePlus 6以速度为导向的测试。
如果您看不懂这张图片,可以试着看绿色指示线以下的图像。超过绿线的任何内容均表示丢帧,在最坏的情况下,会出现明显的卡顿。
EAS在OnePlus 6上的实现很有趣,因为OnePlus 6不像具有相同SoC的Google Pixel一样熟练的使用EAS。调度器参数调整地不太合理,因此这可能解释了为什么它的性能效率不如您预期的那样。它在功耗方面非常保守,系统会在大多数工作中优先考虑低功耗核。
可调参数只是传递给CPU governor的一组参数,这些参数会改变governor在频率方面对某些情况的反应。然后,调度器决定将任务分配在不同处理器上。OnePlus 6的可调参数能在低功耗核上设置任务的优先级,可是这并不起什么作用。而 Google Pixel 2具有巨大的输入提升能力,所有8个核始终保持在线状态。Google还使用了一个中断负载均衡,它有助于消除丢帧并提高性能。
那么EAS如何工作?为什么仅在特定条件下如此有效?
功耗感知调度(EAS)需要使用功耗模型,就像上面提到的,EAS需要大量测试工作才能使其完美。EAS试图统一内核的三个不同核心部分,它们各自独立发挥作用,而功耗模型则有助于统一它们。
-
Linux调度程序(CFS,如上所述)
-
Linux cpuidle
-
Linux cpufreq
将调度器下的三个部分统一并且一起计算可以降低功耗,因为一起计算可以使它们尽可能高效。CPUIdle尝试确定CPU何时应进入空闲模式,而CPUFreq尝试确定何时升高或降低CPU频率。这两个模块的主要目标都是节能。不仅如此,它还将进程分为四个cgroup,即top-app,system-background,foreground和background。将要处理的任务放入这些类别之一,然后为该类别分配CPU资源,并在不同的CPU核上委派工作。top-app要求最优先地被完成,其次是foreground,background,然后是system-background。从技术上讲,background与system-background具有相同的优先级,但是system-background通常也可以访问更多的小核。实际上,EAS正在将Linux内核的核心部分整合到一个进程中。
唤醒设备时,EAS将选择处于最浅的空闲状态的核,从而将唤醒设备所需的功耗降至最低。这有助于减少使用设备时所需的功率,因为如果不需要,它不会唤醒大簇(big cluster)【big cluster的概念见下图】。负载跟踪也是EAS极其重要的一部分,有两种选择。“每实体负载跟踪”(Per-Entity Load Tracking PELT)通常用于负载跟踪,然后该信息用于确定频率以及如何在CPU上委派任务。也可以使用“窗口辅助的负载跟踪”(Window-Assisted Load Tracking WALT),它是Google Pixel上使用的。我们论坛上的许多EAS ROM(例如VertexOS)都选择使用WALT。许多ROM会发行WALT和PELT两个版本的内核,因此由用户决定。WALT更具突发性,CPU频率峰值很高,而PELT试图让频率保持连贯性。负载跟踪器实际上并不影响CPU频率,它只是告诉系统CPU使用率是多少。较高的CPU使用率需要较高的频率,因此PELT的连贯性意味着它将缓慢地调高或调低CPU频率。PELT确实会趋向于更高的CPU负载报告,因此它可能会以更高的耗s电来提供更高的性能。但是,由于两种负载跟踪方法都在不断地修补和完善,因此目前尚无法真正说出哪种负载跟踪系统更好。
很明显,无论使用哪种负载跟踪方法,效率都会提高。使用跟踪方法不是仅仅在任何处理器上处理任务,而是可以分析任务并估算运行该任务所需的功耗。这种巧妙的任务分配方式意味着任务可以更加高效的完成,同时还可以使整个系统更快。EAS旨在以最小的功耗获得最流畅的UI。负载跟踪需要其他外部组件(例如schedtune)的参与。
Schedtune在每个cgroup中由两个可调参数定义,以确保对要完成的任务进行更好的控制。它不仅可以在多核CPU上分散任务,而且为了确保更快地完成时间敏感型任务,来决定是否增加感知的负载。这样,用户使用的前台应用程序和服务不会减慢速度,也不会引起不必要的性能问题。
虽然EAS是今后的一件大事,但也可以说它已经存了好一段儿时间。随着越来越多的设备采用EAS而进军主流市场,移动设备处理效率的新时代即将到来。
轮转,CFS,HMP和EAS的优缺点
虽然我的画图技术略差,但我努力拼凑了一张图片,其中应该总结出了每种调度器的优缺点。
我要特别感谢XDA公认的贡献者Mostafa Wael, 他对EAS各个方面的解释极大地帮助了本文的实现。我还要感谢XDA注册开发人员joshuous,XDA注册开发人员RenderBroken 和Mostafa Wael有关EAS的文章。那些对EAS相关内容感兴趣的人,Linaro有很多关于EAS的文档,您可以阅读。