内核调度程序如何通过定时器中断保持时间量精度?

mut*_*ity 2 cpu scheduling process linux-kernel

根据我的阅读,有一个由硬件调用的定时器中断,它经常执行并将控制权从正在运行的进程转移回内核/调度程序,然后内核/调度程序能够确定正在运行的进程是否已超过其时间量,如果是,则运行另一个任务.

这似乎不精确。

例如:如果定时器中断是每 1 个单位

并且调度程序算法将 cpu 绑定进程时间量确定为 1.5 个单位,它实际上将获得 2 个单位的 CPU 时间。

或者调度程序是否只以中断计时器为单位为进程提供时间量?

小智 5

Linux 的调度程序 (CFS) 通过首先定义每个线程将运行一次的时间段来为线程分配时间片。该时间段由sched_slice()函数计算,取决于 CPU 上的线程数,以及可从用户空间(sysctl_sched_latencysysctl_sched_min_granularity)设置的 2 个变量:

如果线程数大于sysctl_sched_latency / sysctl_sched_min_granularity; 那么这个时期将是nr_threads * sysctl_sched_min_granularity; 否则期间将是sysctl_sched_latency

例如,在我的笔记本电脑上,我有以下值:

    % cat /proc/sys/kernel/sched_latency_ns
    18000000
    % cat /proc/sys/kernel/sched_min_granularity_ns
    2250000
Run Code Online (Sandbox Code Playgroud)

因此,sysctl_sched_latency / sysctl_sched_min_granularity = 8。现在,如果我在 CPU 上的线程少于 8 个,那么每个线程将被分配 18.000.000 纳秒(即 18 毫秒);否则,每个将分配 2.250.000 ns (2.25 ms)。

现在,考虑到这些值,如果我们使用以下命令查看滴答频率(在内核编译时定义):

    % zcat /proc/config.gz | grep CONFIG_HZ
    # CONFIG_HZ_PERIODIC is not set
    # CONFIG_HZ_100 is not set
    # CONFIG_HZ_250 is not set
    CONFIG_HZ_300=y
    # CONFIG_HZ_1000 is not set
    CONFIG_HZ=300
Run Code Online (Sandbox Code Playgroud)

所以,在我的笔记本电脑上,我每秒有 300 个滴答声,这意味着每 3 毫秒一个滴答声。这意味着在我的情况下,CPU 上有 8 个以上的线程,我的时间片精度会有所下降(应该运行 2.25 毫秒的线程将运行 3 毫秒),但我可以通过重新编译我的具有更频繁滴答声的内核。

但是,需要注意的是,这实际上不是问题,因为正如其名称所示,CFS(Completely Fair Scheduler)旨在公平,这里就是这种情况。