• Feeds

  • Posts Tagged ‘kernel’


    谈Linux内核定时器

    看了3个周末的Linux内核,包括前两周总结的进程与线程锁与同步。当时研究这个的原因是因为某个程序CPU context switch过高。不过到现在相关的背景知识也了解了,问题也早已经解决了,所以暂时也没有进一步的兴趣驱动去研究内核了,这里是终结篇。:)

    在应用程序运行的时候,特别是抢占式的操作系统里面,内核怎么样取得控制权?这依赖硬件支持的系统定时器来实现。内核中有非常多的功能由定时器触发。系统定时器以固定的频率触发,这个频率称为tick rate(HZ),每个触发周期的时间叫做tick, 它等于1/HZ秒。触发后系统会转到内核相应的handler去处理。

    在系统定时器中断时候内核需要做以下事情

    • 更新uptime, time of day, resource及处理器使用状态
    • 检查多处理器是否负载均衡
    • 检查当前进程是否timeslice是否用完,如果用完则重新分配下阶段计划(reschedule)
    • 运行应用程序自定义的定时器(dynamic timers)

    了解了tick rate之后才能比较好理解为什么sleep(), timer等API声称都不是提供精确的时间,因为cpu一个任务timeslice没运行完,系统是不会马上切换到这些dynamic timer的进程的。

    Linux 2.5以上将tick从100改成1000,相当于系统时钟从10ms变成每1ms要中断一次,当时也引起较大的争议。

    改成1000的优点有:

    • 系统时钟精度更高更准确。
    • 系统调用如poll(), select() 等依赖系统时钟的调用性能得到很大改善。
    • 内核实时运行指标如资源占用,uptime更准确。
    • 抢占式机制更精确。

    缺点:
    我们知道定时器频繁被触发必将会增加开销,降低throughput。这是很多人反对改成1000的理由。原理上它在CPU的时间中断上将会增加10倍的开销。但由于现代CPU硬件速度的变快。大家也逐渐认可了新的调整不会给整体性能带来大的影响。如果在意这一点的可以重新编译内核, 将<asm/param.h>中HZ的值由1000降低。目前可以接受的值有100,500和1000。

    Linux 2.6.21 又增加了一种叫dyntick的技术,dyntick就是在系统空闲的时候,彻底停止时间中断, 避免cpu空转,它会带来节能方面的好处。详情可参看Clockevents and dyntick。这是个新的技术,一般的书上都没来得及写进去。

    比较感兴趣的后续课题是virtualization系统中的timer实现。