0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

讨论一下Linux的各种躺平姿势

Linux阅码场 来源:Linux阅码场 作者:Liam 2021-06-13 17:59 次阅读

CPU 就和皮鞋厂的工人一样, 无可奈何之时也得躺平。历代CPU的架构师都有一颗仁慈的心——给自己的产品留下了躺平的功能,而且是一代更比一代强。相关的指令有HLT/PAUSE/MWAIT/UMWAT/TPAUSE,其中我最喜爱的是UMWAIT,它的妙处我们后面再说。

当然经理并不会轻易让CPU工人去摸鱼, 必须满足一定的条件。Linux 内核中那么严格说来是由Scheduler 来判断目前的工作量是否饱满。如果工作量实在不够,也只好让CPU划划水, 睁只眼闭只眼, 好歹省点电费不是。虽然在CPU层面摸鱼的手段花样百出, 但是在OS层面只有一个抽象的概念就是IDLE。在这个时候经理表面上放任CPU工人划水, 其实打的是省电的小九九,这也算是Win-Win的帕累托改进。那么问题就来了, Scheduler 到底是如何判断当前工作量不饱满呢?

调度器中idle 触发条件

Linux Scheduler 为每一个CPU工人都维护了一个RunQueue 可以认为是一个任务列表, 当且仅当这个列表里所有的任务都不是runnable的状态时, Scheduler 才会切换到idle process。也就是说这个时候CPU工人完全无所事事, 必须休息节省体力以及节省电费! 同时还要注意可以通过nohz/nohz_full启动参数减少tick 中断对正在休息的CPU工人的干扰!

身世显赫

那么首先我们要考虑得是idle进程从何而来,在描述细节之前我先剧透一下, idle进程虽然名字听起来不怎么样, 但是出身显赫。首个idle进程实际上转化自0号进程!内核成为了生活的真相帝, 躺平并不是人人都能拥有的选项!

具体的过程则是说来话长. 在开辟鸿蒙之初, kernel 所有的进程之始祖是一个静态的结构体:

struct task_struct init_task

init_task 并非由任何kernel API所创建, 是所有进程的祖先, 名副其实的the one。

它肩负了非常重要的职责, 例如创建首个内核线程kernel_init。从而达到 一生二,二生三,三生万物 的效果。不过今天这些不是本文的重点, 重点在于大功告成之际, init_task 并未事了拂衣去而是默默的转化成了idle 进程。它继续无言的守护着整个系统, 俯首甘当孺子牛啊。

这里参见代码 init/main.c line 451,这里是函数rest_init 的最后阶段大家可以发现调用了 cpu_startup_entry 这个函数。

我们可以跳转到 kernel/sched/idle.c 来一窥细节. 这里第一个arch_cpu_idle_entry 是可选接口,x86并没有实现,核心中的核心还是函数 do_idle()-- just 躺平.

如果没有在启动时强制idle 模式为poll, 则我们将在这里进入真正的躺平函数 cpuidle_idle_call.

在smp系统中 core0 以外的其它core 也会通过 start_secondary 函数最终产生0号进程且调用cpu_startup_entry 来进入idle loop之中。

CPU各种“躺平”的姿势

各个厂子出产的CPU工人的idle 姿势也是慢慢演化的, 从简入繁, 花样百出。下面我们一起来浮光掠影的看一下这些"超能力"。

X86

HLT

这是初代的idle 指令, 于486DX时代引入. 首先只有在ring0的特权级别才能执行HLT指令, 同时执 行的效果是 CPU 进入了C1/C1E state(参考ACPI标准)。严格说起来只能算是摸鱼0.1v。APIC/BUS /CACHE 都是照常运转, 只要中断发生, CPU工人立即就要回到产线继续搬砖。C1E 稍微又优待了CPU点, 停止内部时钟又降了压, 比较体贴。

PAUSE

这个也是非常早期的指令(Pentium 4)许可CPU 工人打个盹,大概从几个到几十个cycles吧(各代CPU有差异)。为什么要打盹呢?其实主要是要降低CPU工人在特定情况下(spin-lock)给内存控制器带来的压力,与其让CPU工人阻塞了内存控器, 不如让他打个盹吧。在最近的几代Xeon之上还附带了降低功耗的buff。

MWAIT/MONITOR

新一代CPU架构师回顾了前辈的设计, 觉得CPU工人的权力完全没有得到充分的照顾, 应该给予更进一步的休息机会乃至真正的躺平!而且唤醒的条件又多了一个, 除了中断这种强唤醒模式以外, 又加了内存的CacheLine Invalidate唤醒。你的邻居CPU 除了敲门以外还多了拿橡皮筋弹窗户玻璃的渠道。首先这两条指令也只能在ring0 级别执行, 首先是调用MONITOR 地址范围, 其次是MWAIT 进入休眠,一旦该地址的内存被任何其它的主体修改, 则唤醒CPU工人起来继续搬砖。同时这次最大的改进是可以通过MWAIT 进入各种不同的Cstate。其中C6 是我心目中真正的躺平 CPU 电压可以归0同时cache 也停, 实至名归啊。

最常见的C State 状态详细描述,引自[2]

Cstate Name Description
C0 Operating State CPU fully turned on
C1E Enhanced Halt Stops CPU main internal clocks via software and reduces CPU voltage; bus interface unit and APIC are kept running at full speed
C3 Deep Sleep Stops all CPU internal and external clocks
C6 Deep Power Down Reduces the CPU internal voltage to any value, including 0 Volts

UMWAIT/UMONITOR

MWAIT虽好, 但是奈何必须在ring0特权级下执行, 如果是一些特定的用户级应用例如DPDK, Linux的 idle driver 是很难得到执行的机会,所以CPU架构师又生怜悯之心, 允许CPU在用户级也能进入躺平的模式, 不过作为妥协连C1 state都不行,只能进入 C0.1/C0.2 等神秘模式。效果还有待观察,不过话说回来SPR这代Xeon才开始支持....距离上市少说还得1年之久。

TPAUSE

UMWAIT 指令的升级加强版, 附带了一个timer。TPAUSE 可以让CPU工人根据规定好的时间进行休息, 时间一到, 立刻继续搬砖。当然这也是一个簇新簇新的指令,大家还要等待SPR。

ARM

ARM的Idle-state 级别情况比较复杂一些, 更多的是和具体的芯片实现相关. 但是总体上也是把握几个大的类别:

只是停止CPU内部时钟

CPU降频

停止给Cache供电

停止给CPU供电

和X86 相比 Arm的唤醒机制没有和MESI协议连接有些遗憾(也就是没有实现通过MEM 地址监控的方式达成唤醒).

YEILD

这条颇为类似 PAUSE基本功能接近,使用场景也接近(spin lock).

WFE/WFI

这两条指令顾名思义 wait for event/ wait for interrupt,中断这条大家都可以理解类似HLT,那么event这条就值得看看了。ARM架构可以从一个CPU向所有其它CPU 发送event(sev 指令),我的理解类似IPI广播,收到了此event的CPU如果处于idle状态, 则需要立即唤醒。(注:和宋老师讨论以后发现 event 和IPI的一个区别是不需要ISR来响应,同时event并不能唤醒由于WFI指令进入的idle,这个有点囧,反过来中断可以唤醒由于WFE进入的idle。这两个躺平姿势水很深啊)

软件实现

除了硬件的各种花式躺平技术之外还有两类“伪躺平”技术。

idle polling

通过启动参数, 我们可以指定cpu的idle 进程并不调用硬件提供的idle功能而仅仅是polling, 这种情况主要用于需要极低的CPU从idle状态返回时延的场景。那么如果压根没有进入实际的idle状态,当然时延是极低的,同时也能融入到idle整体的框架,不至于破坏规矩开特例。

halt-polling

在打开虚拟化的场景下, 事情就变得更加有趣了。大多数情况下, qemu 会缺省的只对guest 提供HLT指令作为idle的唯一机制,但是 HLT 指令毫无悬念的会触发VMEXIT。虽然说大多数情况下kvm看到exit reason 是HLT 也只是执行poll而已, 但是VMEXIT/VM_RESUME 还是如此的痛,毕竟几千个cycles已经无谓流逝, 追求极致的我们怎么能放任资源浪费。于是Redhat在Guest端引入了halt poll 机制, 也就是说如果matrix中的CPU工人首先开始假摸鱼(poll), 如果假摸鱼时间超过了阈值才真的去触发HLT指令。如果很快就被从假模鱼状态拉回去搬砖, 则省去了出入matrix的费用(经理得意的笑了)。

最后软件硬件各路躺平姿势花样繁多, 内核无奈又祭出了抽象大法把idle的时长与返回时延的选择与具体执行idle的机制分离开来。

idle governor 就负责做时长与时延的选择,也可以称为 idle -select。

idle driver 则是负责通过我们上面描述的各种软硬件机制来实现governor指定的目标。同时向governor menu 经理提供各种不同机制的性能参数,以供menu经理选择,就是所谓的idle-enter。

idle governor 缺省的算法只有一个就是menu, 还有3个候选的ladder/TEO/haltpoll 算法但是一般需要重新编译内核来激活。

ladder 算法故名意思, 是首先从能耗较高/返回时延较小的状态开始,当系统idle超过了阈值再进入更深的节能状态,从而逐步升级节能状态。俗称添油战术也可以美其名曰“快速迭代”。

menu 算法单从名字看则有点让人摸不到头脑,其内部机制也确实颇为复杂,menu算法主要是要在节能状态的停留时间与系统能容忍的返回时延之间做权衡以达到最佳效果。

请原谅我非常不精确地描述一下menu。menu仿佛一个非常敬业的经理凡事都要精算做出最优选择,CPU工人一旦休息再想打起精神干活这个转换是有一个代价的, 往往需要口头鼓励(画饼)+物质鼓励(肉夹馍)。那么经理就要考虑如果工人休息时间太短,休息的好处远低于让CPU工人重新振作的代价,那么这个休息就是不合理的(无情啊)。而且休息也有好些种类, 从假休息到完全躺平, 到底哪一种休息状态才是收益比最佳的? menu会无情的选择那个休息带来好处大于重新振作代价的方案。同时menu经理还会受到来自客户的压力, 时延也是要满足的。客户的耐心大抵上都是不好的, menu经理会疯狂试探客户的底线。它选择的方案是满足客户耐心上限的情况下CPU工人消耗能耗最少的方案。同时做到以上两点 menu经理大约才能有希望完成OKR/KPI。

结语

今天我们一起浮光掠影的讨论了一下Linux的各种躺平姿势,从中能领略到一代代CPU架构师对CPU打工人的关爱。最后我衷心的祝愿CPU打工人在层出不穷的各类躺平技术加持下,最终能同各位经理一起实现碳中和的OKR/KPI。

原文标题:漫话Linux之“躺平”: IDLE 子系统

文章出处:【微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10824

    浏览量

    211095
  • Linux
    +关注

    关注

    87

    文章

    11219

    浏览量

    208879

原文标题:漫话Linux之“躺平”: IDLE 子系统

文章出处:【微信号:LinuxDev,微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    什么是交叉调整率?怎么改善?

    生活中多路输出电源应用广泛,但是多路输出电源的交叉调整率是个头疼的问题。今天,我们就来讨论一下交叉调整率的改善之道!
    的头像 发表于 10-24 11:15 229次阅读
    什么是交叉调整率?怎么改善?

    触摸屏驱动板无法烧写程序的相关原因

    每次听到别人说是什么原因导致触摸屏驱动板无法烧写程序,就很想去讨论一下。今天就跟大家聊聊到底是什么原因导致的。
    的头像 发表于 10-21 11:19 152次阅读

    欢创播报 支付宝“碰一下”正式发布

    1 支付宝“碰一下”正式发布 近日,在支付宝开放日上,支付宝宣布升级条码支付体验,推出“支付宝碰一下”,用户无需展示付款码,解锁手机碰一下商家收款设备,最快步完成支付。据介绍,“碰
    的头像 发表于 07-11 11:32 848次阅读
    欢创播报  支付宝“碰<b class='flag-5'>一下</b>”正式发布

    STM8L单片机的低功耗问题在软件中如何设计?

    大家来讨论一下STM8L单片机的低功耗问题在软件中如何设计?
    发表于 05-14 07:34

    Bladed软件的使用问题讨论

    你们使用Bladed软件有出现这种情况过吗?有使用过此软件的大家可以讨论一下吗?
    发表于 05-08 17:34

    请问Systick配置为多长时间中断次合适?

    般情况,常用的配置SysTick是用MCU运行系统频率除以1000(1ms)或者除以100(10ms),那如果配置成10(100ms)的时候,结果会怎样?讨论一下:SysTick最小和最大配置成多长时间?
    发表于 05-06 06:07

    STM32可以使用手机APP,蓝牙或者WIFI软件升级MCU软件的方法吗?

    STM32有方法可以使用手机APP,使用蓝牙或者WIFI 软件升级MCU软件的方法吗? 大家讨论一下,个人决定这个方向很好用,可能是以后的趋势。
    发表于 04-09 07:52

    什么是LDO?浅析低压差稳压器 (LDO) 中的噪声及电源抑制比

    在本文中,我们将介绍低压差 (LDO) 稳压器中噪声和电源抑制比 (PSRR) 的影响。让我们简单讨论一下什么是 LDO。
    的头像 发表于 03-15 17:12 3217次阅读
    什么是LDO?浅析低压差稳压器 (LDO) 中的噪声及电源抑制比

    深入讨论一下模拟式UDP无线中继技术的缺陷

    在《WiMinet 评说 1.2:多跳无线网络的现状》文中,我们提到:在室外长距离的无线自组织网络中,由于节点之间的链路损耗较大,其链路预算相对不足,其包误码率PER会相应升高,也就是丢包概率 p 会比较大;
    的头像 发表于 02-23 10:53 888次阅读
    深入<b class='flag-5'>讨论一下</b>模拟式UDP无线中继技术的缺陷

    请问有人用过瑞芯微自定义3A算法模块吗

    目前也研究了好阵了,想请教一下如何开发自己的3A算法库或者别的图像处理算法库。想和各位讨论一下
    发表于 01-25 10:15

    Mysql索引是什么东西?索引有哪些特性?索引是如何工作的?

    作为开发人员,碰到了执行时间较长的 sql 时,基本上大家都会说” 加个索引吧”。但是索引是什么东西,索引有哪些特性,下面和大家简单讨论一下
    的头像 发表于 12-24 16:20 1197次阅读
    Mysql索引是什么东西?索引有哪些特性?索引是如何工作的?

    什么是数据备份?真实环境的数据备份讨论

    什么是数据备份?就是把数据再次备份一下。感觉是废话?大道本来就很简单。
    的头像 发表于 12-20 10:23 648次阅读
    什么是数据备份?真实环境<b class='flag-5'>下</b>的数据备份<b class='flag-5'>讨论</b>

    介绍一下芯片的VIA pillar

    Via pillar,又可以叫Via ladder。貌似Cadence家喜欢叫pillar,synopsis喜欢叫ladder,我也不知道它们为啥不能统一一下名称。
    的头像 发表于 12-06 14:00 788次阅读

    ubuntu和linux的区别

    Ubuntu和Linux是两个相关但不完全相同的概念,它们之间有着些区别。在开始深入讨论Ubuntu和Linux之间的区别之前,让我们首先了解一下
    的头像 发表于 11-27 17:06 2311次阅读

    高效稳定管理电源的正确“姿势”!

    高效稳定管理电源的正确“姿势”!
    的头像 发表于 11-23 09:04 392次阅读
    高效稳定管理电源的正确“<b class='flag-5'>姿势</b>”!