【问题标题】:Linux' hrtimer - microsecond precision?Linux' hrtimer - 微秒精度?
【发布时间】:2013-02-03 08:24:08
【问题描述】:

是否可以在 Linux 主机上以微秒精度执行任务?即,我想在特定的时间执行一项任务。我知道,Linux 不是实时系统,但我正在寻找 Linux 上的最佳解决方案。

到目前为止,我已经创建了一个内核模块,设置了 hrtimer 并测量了输入回调函数时的抖动(我不太关心实际延迟,重要的是抖动)-大约 20- 50us。这并不比在用户空间中使用 timerfd 好很多(也尝试为进程使用实时优先级,但这并没有真正改变任何东西)。

我正在运行 Linux 3.5.0(只是一个示例,尝试了从 2.6.35 到 3.7 的不同内核),/proc/timer_list 显示 hrtimer_interrupt,我没有在禁用 hrtimer 功能的故障安全模式下运行。在不同的 CPU 上进行了尝试(Intel Atom 到 Core i7)。

到目前为止,我最好的想法是将 hrtimer 与 ndelay/udelay 结合使用。这真的是最好的方法吗?我不敢相信不可能以微秒精度触发任务。在内核空间中将代码作为模块运行是可以接受的,但如果代码没有被其他任务中断,那就太好了。我不太关心系统的其余部分,该任务每秒只会执行几次,因此每次执行任务时使用 mdelay/ndelay 将 CPU 烧掉几微秒并不重要。不过,我更喜欢更优雅的解决方案。

我希望这个问题很清楚,找到了很多关于计时器精度的主题,但没有真正解决这个问题。

【问题讨论】:

    标签: linux timer module kernel real-time


    【解决方案1】:

    你可以从用户空间做你想做的事

    1. 使用clock_gettime()CLOCK_REALTIMEnano-second 分辨率获取时间
    2. 使用nanosleep() 让出CPU,直到您接近执行任务所需的时间(至少是milli-秒分辨率)。
    3. 使用带有clock_gettime() 的旋转循环,直到达到所需时间
    4. 执行您的任务

    clock_gettime() 函数在最近的内核和现代 x86 处理器中被实现为 VDSO - 它需要 20-30 nanoseconds 才能获得 nano-second 分辨率的时间 - 你应该每micro-秒能够调用clock_gettime() 30 次以上。使用这种方法,您的任务应该在预定时间的 micro-second 的 1/30 内分派。

    【讨论】:

    • 虽然目前还不能完全确定用户空间解决方案是否能解决我的问题,但该解决方案解决了以微秒精度执行任务的问题。
    【解决方案2】:

    默认的 Linux 内核计时器每毫秒计时一次。微秒远远超出了当前用户硬件的能力。

    您看到的抖动是由许多因素造成的,例如中断处理和服务更高优先级的任务。你可以通过仔细选择硬件来减少它,只启用真正需要的东西。内核的实时补丁系列(参见HOWTO)可能是进一步减少它的一个选项。

    请始终牢记,任何收益都会在交互性、稳定性以及(最后但并非最不重要的)您在构建、调整、故障排除和防止纸牌屋分崩离析方面的时间方面付出一定的代价。

    【讨论】:

    • “微秒远远超出了当前用户硬件的能力。”我不敢苟同——处理器的 2GHz 恐龙以 0.5 纳秒的间隔滴答作响。如果您假设每条指令平均有 10 个时钟频率非常高,并且实现一个循环的同样高 50 条指令,那么每个循环仍然是 250 纳秒,这意味着在现代硬件上很容易实现比毫秒分辨率更好的时序循环......
    • @twalberg,你的 CPU 在一微秒内执行了多少条指令?一打?
    • Pentium 4 硬件程序员参考似乎表明大多数常用指令的延迟远低于 10 个时钟,这是从 2002 年开始的。2GHz 的 10 个时钟(现代 CPU 运行接近两倍)是 5 纳秒 - 因此每微秒很可能超过 200 条指令。显然,缓存问题和数据危害和其他事情可以在一定程度上缓和这种情况,但是紧密的时序循环可以运行得非常快......
    猜你喜欢
    • 1970-01-01
    • 2015-06-25
    • 1970-01-01
    • 2013-04-06
    • 2014-01-11
    • 1970-01-01
    • 2015-07-20
    • 2011-02-04
    相关资源
    最近更新 更多