5

其中sched_fair.c有:

unsigned int sysctl_sched_latency = 5000000ULL //5m 

unsigned int sysctl_sched_min_granularity = 1000000ULL //1ms

我知道 Linux 公平时间片取决于 nr_running 和这个公平任务的相对权重,但通过代码研究,我发现主要思想是将时间片保持在 1 到 5 毫秒。如果我理解错了,请纠正我。我在这里一定是错的,但我就是不知道怎么做!

还知道 HZ 或每秒系统滴答数或每秒计时器中断数对于 arm 机器(以及大多数非桌面机器)通常为 200 或 100,这给了我们 5 到 10 毫秒的滴答声速度。

时间片通过启动 rq->hrtick_timer inset_next_entity()来执行,每次公平任务被安排运行,并调用resched_task()超时回调函数hrtick()。该计时器只是计时器 irq 处理程序在每个滴答时处理的排队计时器之一,timer_tick()...。run_local_timer()似乎没有其他隐藏的秘密。

那么我们如何才能得到一个小于 5 ms 的时间片呢?请帮助我理解这一点。非常感谢!

4

1 回答 1

2

正如 Robert Love 的 Linux Kernel Development 中所述,缩短时间片的唯一方法是增加正在运行的进程(或优先级低于其他进程的进程)的数量。

运行进程数量的增加需要缩短时间片以保证适当的目标延迟(但时间片的下限是最小粒度)。但是不能保证进程会在给定的时间片内被抢占。那是因为时间计费是由定时器中断驱动的。

增加 HZ 的值会使定时器中断更频繁地发生,这使得时间计费更加宝贵,因此重新调度可能会更频繁地发生。


vruntime变量存储一个进程的虚拟运行时,它是由可运行进程的数量标准化的实际运行时。在理想的多任务系统上,所有进程的 vruntime 都是相同的——所有任务都将获得同等、公平的处理器份额。

通常,时间片是目标延迟除以正在运行的进程数。但是当正在运行的进程数接近无穷大时,timeslice 接近 0。由于这最终会导致不可接受的切换成本,CFS 对分配给每个进程的时间片施加了一个下限。这个下限称为最小粒度。所以时间片是 和 之间的sysctl_sched_latencysysctl_sched_granularity。(见sched_timeslice()

vruntime变量由 管理update_curr()update_curr()由系统计时器定期调用,并且每当一个进程变为可运行或阻塞时,变为不可运行。

为了驱动任务之间的抢占,hrtick()调用task_tick_fair()每个定时器中断,然后调用entity_tick(). entity_tick()调用update_curr()更新进程vruntime,然后调用check_preempt_tick(). check_preempt_tick()检查当前运行时间是否大于理想运行时间(时间片),如果是,则调用resched_task()设置TIF_NEED_RESCHED标志。

TIF_NEED_RESCHED设置时,schedule()在最近的可能场合被调用。

因此,随着 值的增加HZ,定时器中断更频繁地发生,从而导致更宝贵的时间计费,并允许调度程序更频繁地重新调度任务。

于 2013-07-01T12:39:50.163 回答