CPU没有任务时,认为内核把什么都不做作为一件简单的任务是合理的,但事实却并非如此。在Kernel Recipes 2018,Rafael Wysocki讨论了当CPU没事儿的时候干啥,内核如何处理,在当前阶段存在的问题,以及他最近重做的内核idle loop对非工作中的系统的省电性的提升。
idle loop(在内核的空闲循环,也是空闲任务,空闲也是任务)是Wysocki维护的一个内核子系统,控制CPU在没有任务的时候做的事。为了方便讨论,Wysocki先提出了定义:对于一个CPU就是一个能够从内存取指令并在其他CPU执行指令的同时执行指令的实体。在一个简单的单核单指令流系统,此核即CPU;如果处理器有多个核,那么每个核都是一个CPU。如果每个核都为同步指令expose多个接口,也就是Inter所谓的超线程,那么每一个超线程都是一个CPU。
一个CPU没task运行的时候,就是idle。更精确的说,linux内核的内部调度类,包含特殊的idle类。如果在这些调度类中都没有任务,则CPU被认为是idle,如果硬件没有对此没啥考虑,则CPU就会执行无用的指令直到有任务需要它做。无论如何,这都是浪费电,所以大多数CPU都支持由内核操作进入一些低耗电状态,直到它们需要执行任务。
idle状态的进入或退出不是没有消耗的。进入或退出都需要一些时间,并且耗电较普通状态也会有短暂上升。尽管越多的深度idle状态会降低耗点,但同时也会提升进入/退出idle的能耗。这就意味着对于短idle周期来说,浅度idle状态才能最好的利用系统资源;对于长 idle周期,深度idle状态将会合理的节省idle周期内的能耗。因此内核最感兴趣的就是在决定idle深度前,怎样预测CPU将会idle的周期。这就是idle loop的工作。
在idle loop,CPU调度器因为没有任务而发现CPU空闲。调度器就会执行到idle管家(本博主擅自起的名字,管家-governor),管家会尽可能的预测合适的idle状态。当前内核有menu和ladder两个idle管家,分别面向不同场景,不过大体都是做同样的事:追踪系统状态,CPU idle时间和结束idle的时长。这是为了预测一个新的CPU idle将要持续的时间,以及其合适的idle状态。
这一工作由与CPU调度器tick而变得困难,tick是为了分时共享CPU:在单CPU上跑多个任务,每个任务都只能运行一会儿,其他我就不说了。这一tick不需要在idle的CPU上发生,因为也没有任务需要切换。另外,如果tick允许运行在otherwise-idle CPU,它会限制CPU保持idle的时长,是管家不能选择更深的idle状态。因此在4.16以后的内核中,调度器会在调用管家之前关闭tick。当CPU被中断唤醒,调度器决定是否有任务,有任务才开启tick。
如果管家预测结果是长idle,idle周期也确实长,则关键命中:CPU将会进入深度idle状态,耗电节省,但如果idle周期短,则未命中,因为进入深度idle状态的开销将不能由省电补偿。更糟糕的是,当管家预测为短idle,若实际为长idle则未命中浪费电,若实际为短idle,关/开tick就不必要了,因为关/开tick也是需要开销的。
Wysocki 考虑尝试重新设计关于这方面的管家,认为关键问题是在管家被调之前,也就是推荐idle状态之前tick就关闭了。因此,他为4.17内核重写idle loop,使tick在管家调用之后再被操作。如果推荐长idle,tick就会关闭,也就不会过早唤醒CPU。如果推荐短idle,则tick会保持开启以避免关/开tick的开销。这就意味着tick同样是安全的唤醒CPU的事件,在idle比预期长的情况下,使管家有机会改正。
当idle CPU被中断唤醒,无论是由于tick或其他时间,调度器迅速决定是否有任务要做。如果有,则重启tick(如果关了);如果没有,管家会立刻被再次调用。这就意味着无论tick运行与否,管家都会被调,因此管家需要重写来将此情况纳入考虑。
重查命中与否的表,Wysocki认为情况将会由此次重写改善。如果长idle被预测到,tick将会停止,因此不需要改;实际为长idle则命中,短则失败。但如果预测到短idle,而实际也是短,我们将会节省关/开tick的开销;如果实际为长idle,未关闭的定制器将会唤醒CPU,并在预测的时候给我们一个额外的bit。
理论并不能代替真实数据,Wysocki已经在很多系统上对此进行了测试。旧idle loop比新的idle耗电多,并且更可预测,耗电量波动更少。如Wysocki所言,新的方法预测得到的短idle比旧的更少,但更正确。
在回答观众提问时,Wysock说,这些工作是架构无关的。Intel的CPU受益更明显,因为他们有相当大的idle状态数组供idle管家选择,给了管家最多的选择来预测正确,不过ARM CPU也同样受益。
节省20%的idle电量消耗可能像是个小的胜利,但其实并不。任何系统想要合理的处理峰值负载,都会需要冗余,就会表现为idle的时段。我服务器(各种业务/mail/talk/file-transfer/vpn/ntp..)上之前一年的CPU使用量大部分都是空闲,节省20%的电量将会是我的服务商非常开心,同样对这个星球也有好处。
ytfy339784578 发布了3 篇原创文章 · 获赞 3 · 访问量 1914 私信 关注