Linux HZ和公平的时间表时间片
在sched_fair.c
它有:
unsigned int sysctl_sched_latency = 5000000ULL //5m
unsigned int sysctl_sched_min_granularity = 1000000ULL //1ms
我知道Linux公平时间片会根据nr_running和这个公平任务的相对重要性而变化,但通过代码学习,我发现主要想法是保持时间片1到5毫秒。 如果我理解错了,请纠正我。 我一定在这里错了,但我无法弄清楚如何!
同时也知道HZ或每秒系统滴答的数量,或者每秒定时中断的次数,对于手臂机器(以及大多数非台式机器),通常为200或100,这给我们5到10毫秒的勾号率。
时间片是由开始rq-> hrtick_timer付诸于行动set_next_entity()
每次一个公平的任务计划运行,并调用resched_task()
在超时回调函数hrtick()
这个定时器只是其中一个排队定时器,它是由定时器irq处理程序在每个tick, timer_tick()
... run_local_timer()
。 似乎没有其他隐藏的秘密。
那么我们如何才能获得短于5毫秒的时间片? 请帮我理解这一点。 非常感谢你!
正如Robert Love的Linux Kernel Development所述,缩短时间片的唯一方法是增加正在运行的进程的数量(或者优先级低于其他进程的进程)。
运行过程中数量的增加创造了缩短时间片的需求,以保证适当的目标延迟(但时间片以最小粒度限制更低)。 但不保证在给定的时间片上进程将被抢占。 这是因为时间记帐是由定时器中断驱动的。
增加HZ的值会使定时器中断更频繁地发生,这使得时间计算更加珍贵,因此重新调度可能会更频繁地发生。
vruntime
变量存储进程的虚拟运行时间,这是实际的运行时间,由可运行进程的数量标准化。 在理想的多任务系统中,所有进程的vruntime都是相同的 - 所有任务都会得到相同的,公平的处理器份额。
通常时间片是目标等待时间除以正在运行的进程的数量。 但是,当正在运行的进程数量接近无穷大时,时间片接近0.由于这最终会导致不可接受的转换成本,CFS会为分配给每个进程的时间片强加一个底线。该底线称为最小粒度。 所以时间片是sysctl_sched_latency
和sysctl_sched_granularity
之间的值。 (请参阅sched_timeslice()
)
vruntime
变量由update_curr()
管理。 系统定时器周期性地调用update_curr()
,并且每当进程变为可运行或块时, update_curr()
变为不可运行。
为了驱动任务之间的占先, hrtick()
在每个定时器中断上调用task_tick_fair()
,然后调用entity_tick()
。 entity_tick()
调用update_curr()
来更新进程vruntime
,然后调用vruntime
check_preempt_tick()
。 check_preempt_tick()
检查当前运行时是否大于理想运行时(时间片),如果是,则调用resched_task()
,它设置TIF_NEED_RESCHED
标志。
当设置TIF_NEED_RESCHED
, schedule()
会在最近的可能场合被调用。
因此,随着HZ
价值的不断提高,定时器中断更频繁地发生,从而导致更加宝贵的时间计算,并允许调度器更频繁地重新调度任务。