【问题标题】:What could be delaying my select() call?什么可能会延迟我的 select() 调用?
【发布时间】:2015-05-20 07:51:12
【问题描述】:

我有一个在 Linux 上运行的小程序(在嵌入式 PC 上,双核 Intel Atom 1.6GHz 和 Debian 6 运行 Linux 2.6.32-5),它通过 FTDI USB 到串行转换器(使用ftdi_sio 内核模块和/dev/ttyUSB* 设备)。本质上,在我的主循环中我运行

  • clock_gettime() 使用 CLOCK_MONOTONIC
  • select() 超时 8 毫秒
  • clock_gettime() 和以前一样
  • 输出两次clock_gettime()调用的时间差

为了获得某种程度的“软”实时保证,该线程以SCHED_FIFO 的最高优先级运行(在top 中显示为“RT”)。它是系统中唯一以此优先级运行的线程,没有其他进程具有这样的优先级。我的进程有另一个优先级较低的SCHED_FIFO 线程,而其他所有线程都在SCHED_OTHER。这两个“实时”线程不受 CPU 限制,除了等待 I/O 和传递数据之外几乎没有什么作用。

我使用的内核没有 RT_PREEMPT 补丁(我将来可能会切换到那个补丁)。我知道如果我想要“适当的”实时,我需要切换到 RT_PREEMPT 或者更好的 Xenomai 等。但尽管如此,我还是想知道“香草”内核上以下时序异常背后的原因:

  • 大约 0.03% 的所有 select() 调用的时间超过 10 毫秒(请记住,超时时间为 8 毫秒)。
  • 三个最差情况(超过 1200 万次调用)分别为 31.7 毫秒、46.8 毫秒和 64.4 毫秒。
  • 上述所有事件都在 20 秒内发生,我认为某些 cron 作业可能受到干扰(尽管系统日志中的信息很少,除了当时正在执行 cron.daily 的事实)。

所以,我的问题是:在这种极端情况下可能涉及哪些因素?这是否只是 Linux 内核本身可能发生的事情,即我是否必须切换到 RT_PREEMPT,甚至是非 USB 接口和 Xenomai,以获得更可靠的保证? /proc/sys/kernel/sched_rt_runtime_us会咬我吗?还有其他我可能遗漏的因素吗?

提出这个问题的另一种方式是,我还能做些什么来减少这些延迟异常而不切换到“更难”的实时环境?

更新:我观察到大约 118.4 毫秒的新“最坏情况”(一次超过 2500 万次 select() 调用)。即使我没有使用具有任何实时扩展功能的内核,我也有点担心,因为很明显可能会错过最后期限超过十分之一秒。

【问题讨论】:

  • 我不是 linux 专家,但也许一个不可抢占的驱动程序中断有一个极端情况需要太多时间?那将是一个驱动程序错误。此外,您的延迟值奇怪地接近 16 毫秒的倍数。我敢打赌,你有很多持续 16 毫秒的电话。也许这是通信失败的连锁重试的症状,或者至少,某些事情失败并被重试。
  • 16ms 倍数的“奇怪接近”只是这个例子的随机效应,我也观察过其他时间。
  • 这是一个无滴答内核,还是你的 HZ 是多少?我记得前段时间select() 的粒度只有 10ms,HZ=100。请改用epoll
  • 在有问题的系统上,CONFIG_HZ=250。但即使粒度是 10 毫秒,我也希望最多 20 毫秒而不是 8 毫秒,而不是 118 毫秒。
  • 从我读到的关于epoll 的内容来看,只有在轮询大量文件描述符(例如stackoverflow.com/questions/8251717/…)时它才会提供优势。我只有一个。您能否指出其他支持epoll 的原因,或者理想情况下为什么epoll 在我观察到的最坏情况下可能做得更好的原因?将不胜感激。

标签: c linux real-time


【解决方案1】:

如果没有更多信息,很难指出具体的东西,所以我只是在这里猜测:

  1. 中断和由中断触发的代码在内核中占用了太多时间,以至于您的实时线程被显着延迟。这取决于中断的频率、所涉及的中断处理程序等。
  2. 优先级较低的线程不会在内核内部被中断,直到它让出 cpu 或离开内核。
  3. 正如this SO answer 中所指出的,CPU 系统管理中断和热管理也可能导致明显的时间延迟(发帖人观察到最多 300 毫秒)。

对于 1.6GHz CPU 来说,118ms 似乎相当多。但是一个意外锁定cpu一段时间的驱动程序就足够了。如果可以,请尝试禁用某些驱动程序或使用不同的驱动程序/硬件组合。

sched_rt_period_ussched_rt_period_us 如果设置为合理的值并且您的代码按预期运行,则它们应该不会成为问题。不过,我会取消对 RT 线程的限制,看看会发生什么。

你还能做什么?编写设备驱动程序!这并不难,并且中断处理程序比实时线程获得更高的优先级。切换到实时内核可能更容易,但 YMMV。

【讨论】:

  • 这些绝对是一些很好的建议,我会看看我能做些什么来禁用一些驱动程序。删除 RT 线程限制 可能 有所帮助(不过我还没有足够的数据来确定)。我没有想到设备驱动程序选项。我会检查这是否适合我的情况。
  • 我知道我没有提供很多具体信息,但我最感兴趣的是一般猜测,所以我知道在哪里挖掘并实际收集更多信息,或者在开始挖掘之前什么时候停止挖掘我的时间太多了。禁用某些驱动程序可能是值得的,但考虑到我必须等待大约 24 小时才能看到是否有改进,这很复杂。内核分析有帮助吗?
  • @mindriot 我会尝试重现最坏的情况,例如生成 cpu 负载、磁盘和/或网络流量等。不确定内核分析是否会有所帮助,因为您正在寻找一种病理情况而不是一般情况。
  • 非常感谢您的意见。我将把这个开放几天,看看是否有任何其他关于我可能忽略的想法出现。如果不是,我会接受您的回答为“不,您可能会错过任何其他事情,寻找有问题的驱动程序或使用更实时的内核是您所能做的一切”。 :)
  • @mindriot 是的,我也很好奇其他人的理论。如果您能够解决此问题,请返回并回答您自己的问题。谢谢!
猜你喜欢
  • 2013-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-22
相关资源
最近更新 更多