当 CPU 空闲(idle)的时候在干什么
今天学习 Linux schedule 框架的时候, 看到如下的图. 这个图列出了 Linux 内核里面的几个 schedule classes, 以及它们之间的关系.
图片源自于: https://deepdives.medium.com/digging-into-linux-scheduler-47a32ad5a0a8
图中各个方块分别表示 Linux 内核的几个 schedule class, 他们按照顺序通过链表的形式连在一起, 当前面的 schedule class 没有需要执行的task的时候, 就去下一个 schedule class 去查找. 当前面所有 schedule class 都没有 task 可以执行的时候, 就去执行 idle 这个虚拟的task.
各个 schedule class 的描述:
- Stop Scheduler (SCHED_STOP) - 停止调度器 这个调度类是用于管理特殊的停止任务,这些任务用于在CPU上停止所有其他任务的执行,通常用于实现CPU热插拔和一些系统级别的调试操作。这个调度类的任务具有最高的优先级,可以抢占系统中的任何其他任务。
- Deadline Scheduler (SCHED_DEADLINE) - 截止时间调度器 这是一种较新的调度类,它为任务提供了严格的截止时间保证。SCHED_DEADLINE使用了称为“恒定带宽算法”的调度策略,允许任务指定它们的运行周期、运行时间和截止时间。这个调度器试图保证每个任务在其截止时间之前都能完成指定的运行时间,适用于对时间敏感度非常高的任务。
- Real-Time Scheduler (RT) - 实时调度器 实时调度类分为两种策略:SCHED_FIFO(先进先出)和SCHED_RR(轮转)。这些策略用于实时任务,这些任务需要快速且可预测的响应时间。在SCHED_FIFO中,只有当运行的实时任务主动放弃CPU或者被更高优先级的实时任务抢占时,它才会停止运行。SCHED_RR与SCHED_FIFO类似,但是它为每个实时任务提供了时间片,使得同一优先级的实时任务可以轮流运行。
- Completely Fair Scheduler (CFS) - 完全公平调度器 CFS是Linux内核的默认调度类,用于普通的非实时任务。它的目标是确保所有运行的进程都能获得公平的CPU时间。CFS使用红黑树来跟踪所有可运行的进程,并尽量平等地分配CPU时间。它基于虚拟运行时间的概念,该时间考虑了进程的权重。权重越高的进程获得的CPU时间越多。
- Idle Scheduler (SCHED_IDLE) - 空闲调度器 这个调度类用于非常低优先级的任务,只有当系统中没有其他可运行的任务时,这些任务才会被调度执行。它通常用于那些可以在系统空闲时运行的后台任务,例如内存压缩守护进程(kcompactd)。
每个调度类都实现了一组调度器框架定义的通用接口,这些接口包括任务入队、出队、选择下一个运行任务等操作。调度器通过这些接口与调度类交互,以实现不同类型的任务调度需求。
Idle 调度器是如何实现的?
参考这篇文章: https://manybutfinite.com/post/what-does-an-idle-cpu-do/
最终是通过 IA 32 指令集的 HTL
(halt) 指令来完成的. hlt
: Halt,使CPU进入halt状态,这是一种低功耗模式。在这种模式下,CPU会停止执行指令,直到下一个中断到来。当系统没有其他任务要执行时,操作系统会执行HLT指令来减少能耗和散热。
查询Linux的最新代码:
https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/irqflags.h#L48asm volatile("sti": : :"memory");
这段代码的作用是使CPU开始响应外部中断,并且立即进入低功耗的halt状态,直到下一个中断到来。这通常用在系统空闲循环或者其他需要CPU等待事件的场合。由于这段代码会改变CPU的中断使能状态,并且可能影响内存的一致性.
在其他处理器架构中,可能有类似功能但名称不同的指令。例如,在ARM架构中,WFI(Wait for Interrupt)指令和WFE(Wait for Event)指令可以用来让处理器等待外部事件或中断。