Hel*_*You 5 linux linux-kernel preemption
在sched_fair.c它具有:
unsigned int sysctl_sched_latency = 5000000ULL //5m
unsigned int sysctl_sched_min_granularity = 1000000ULL //1ms
Run Code Online (Sandbox Code Playgroud)
我知道 Linux 公平时间片取决于 nr_running 和这个公平任务的相对权重,但通过代码研究,我发现主要思想是将时间片保持在 1 到 5 毫秒。如果我理解错误,请纠正我。我在这里一定是错的,但我就是不知道怎么做!
还知道 HZ,或每 s 的系统滴答数,或每秒的定时器中断数,对于 arm 机器(以及大多数非台式机)通常为 200 或 100,这给了我们 5 到 10 ms 的滴答速度。
时间片通过在 rq->hrtick_timer 中启动set_next_entity(),每次公平任务被安排运行,并调用resched_task()超时回调函数hrtick()。该定时器仅仅是由定时器中断服务上的每个节拍处理程序处理的排队计时器之一,timer_tick()... run_local_timer()。似乎没有其他隐藏的秘密。
那么我们怎样才能得到一个小于 5 ms 的时间片呢?请帮助我理解这一点。非常感谢!
正如 Robert Love 的《Linux 内核开发》中所述,缩短时间片的唯一方法是增加正在运行的进程(或优先级低于其他进程的进程)的数量。
\n\n运行进程数量的增加需要缩短时间片以保证适当的目标延迟(但时间片的下限是最小粒度)。但不能保证进程会在给定的时间片内被抢占。这是因为时间统计是由定时器中断驱动的。
\n\nHZ 值的增加使得定时器中断更频繁地发生,这使得时间计算更宝贵,因此重新调度可能更频繁地发生。
\n\n该vruntime变量存储进程的虚拟运行时间,它是按可运行进程数标准化的实际运行时间。在理想的多任务系统上,所有进程的 vruntime 都是相同的\xe2\x80\x94,所有任务都将获得平等、公平的处理器份额。
通常,时间片是目标延迟除以正在运行的进程数。但当运行的进程数量接近无穷大时,时间片接近0。由于这最终会导致不可接受的切换成本,CFS对分配给每个进程的时间片施加了一个下限。这个下限称为最小粒度。所以 timeslice 的值介于sysctl_sched_latency和之间sysctl_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,计时器中断发生的频率会更高,从而导致更宝贵的时间计算,并允许调度程序更频繁地重新调度任务。