4、实时性测试与评估:Cyclictest工具使用、延迟分布分析、最大延迟与平均延迟、抖动(Jitter)评估方法

各位工程师朋友,大家好。这一章我们来聊聊实时性测试。说实话,很多项目在开发阶段跑得挺顺,一到现场就出问题,十有八九是实时性没测透。我见过不少团队,把内核配好、任务优先级设好,就觉得万事大吉了。结果呢?现场一上负载,延迟直接飙到毫秒级,控制周期全乱套。

所以,这一章的核心就一句话:用数据说话。我们得用工具测,用图表看,用指标评。下面我就带大家走一遍完整的实时性测试流程。

4.1 Cyclictest:实时性测试的“万用表”

Cyclictest 是实时 Linux 领域最常用的测试工具。它不复杂,但很管用。说白了,它就是反复测量一个线程从“打算睡”到“真正醒”的时间差。这个时间差,就是延迟。

安装很简单,大部分发行版直接装就行:

sudo apt-get install rt-tests   # Debian/Ubuntu
sudo yum install rt-tests       # CentOS/RHEL

跑一个最基本的测试:

sudo cyclictest -t 1 -p 99 -n -i 1000 -l 100000

参数解释一下:

  • -t 1:只跑一个测试线程
  • -p 99:线程优先级设为 99(最高)
  • -n:使用 nanosleep 做定时
  • -i 1000:间隔 1000 微秒(1ms)
  • -l 100000:循环 10 万次

跑完之后,终端会输出类似这样的结果:

T: 0 (12345) P: 99 I: 1000 C: 100000 Min:      2 Act:    5 Avg:    4 Max:   37

这里 Min 是最小延迟,Avg 是平均延迟,Max 是最大延迟。单位都是微秒。

我的习惯: 我一般会先跑一个短测试(比如 1 万次)看看系统大概情况,没问题了再跑长测试(100 万次以上)。短测试快,能快速发现明显问题;长测试才能暴露那些偶发的“毛刺”。

4.2 延迟分布分析:别只看最大值

很多新手拿到测试结果,第一眼就看 Max 值。Max 值当然重要,但它只是冰山一角。你想想看,如果 99.99% 的延迟都在 10 微秒以内,就偶尔一次跳到 100 微秒,这个 Max 值能代表系统真实水平吗?

所以,我们要看延迟的分布情况。Cyclictest 提供了 -h 参数,可以输出直方图:

sudo cyclictest -t 1 -p 99 -n -i 1000 -l 100000 -h 100

-h 100 表示把延迟从 0 到 100 微秒分成 100 个桶,统计每个桶里有多少次命中。输出结果大概长这样:

# Histogram
000000 0000
000001 0000
000002 0012
000003 0156
000004 2345
...
000010 98765
...
000037 0001
# Total: 100000
# Min Latencies: 00002
# Avg Latencies: 00004
# Max Latencies: 00037

这个数据怎么用?我建议你把它画成柱状图。横轴是延迟值,纵轴是命中次数。一个健康的实时系统,柱状图应该是“瘦高”的,大部分集中在低延迟区域,尾巴很短。

关键判断: 如果柱状图出现“双峰”或者“长尾”,说明系统在某些条件下延迟会突然变大。这时候就要排查了——是不是有中断风暴?是不是有内核线程抢占了?是不是内存紧张导致缺页?

4.3 最大延迟与平均延迟:两个核心指标

这两个指标,我习惯放在一起看。

指标 含义 典型值(PREEMPT_RT) 我的经验
平均延迟 所有延迟的算术平均值 2~10 微秒 反映系统“日常”表现
最大延迟 整个测试周期中出现的最大延迟 10~100 微秒 反映系统“最坏情况”

平均延迟低,说明系统日常响应快。最大延迟低,说明系统稳定、可预测。对于工业控制来说,最大延迟往往比平均延迟更重要。因为控制周期一旦超时,可能直接导致设备动作出错。

我曾经踩过的坑: 有一次做运动控制项目,平均延迟只有 5 微秒,看着很漂亮。结果现场一跑,电机偶尔会“抖”一下。后来抓了 1000 万次测试数据,发现最大延迟达到了 280 微秒。原因是一个 DMA 中断处理得太久。所以,千万别只看平均,一定要看最大

4.4 抖动(Jitter)评估方法

抖动,说白了就是延迟的“波动程度”。两个系统平均延迟都是 5 微秒,但一个最大延迟 10 微秒,另一个最大延迟 100 微秒,后者的抖动就大得多。

评估抖动,我常用三个方法:

  1. 标准差法: 计算所有延迟的标准差。标准差越小,抖动越小。Cyclictest 不直接输出标准差,但你可以把直方图数据导出来,用 Excel 或 Python 算。
  2. 最大-最小法: 用最大延迟减去最小延迟。这个值直观,但容易受极端值影响。
  3. 百分位法: 看 P99.9 或 P99.99 的延迟值。比如 P99.9 是 20 微秒,意味着 99.9% 的延迟都在 20 微秒以内。这个指标对工业控制特别有用,因为它告诉你“几乎所有的”情况。

我个人最推荐百分位法。为什么?因为它能帮你忽略那些“一辈子可能就遇到一次”的极端值,聚焦在“大概率会遇到”的延迟上。

要算百分位,可以用 Cyclictest 的 -p 参数(注意是小写 p,跟优先级的大写 P 不同):

sudo cyclictest -t 1 -p 99 -n -i 1000 -l 1000000 -p 99.9

这个命令会在输出中额外显示 P99.9 的延迟值。

我的建议: 对于硬实时系统(比如伺服驱动、PLC 扫描周期),我要求 P99.99 的延迟不超过控制周期的 10%。比如控制周期是 1ms,那 P99.99 的延迟最好在 100 微秒以内。对于软实时系统(比如数据采集、状态监控),可以放宽到 P99.9。

4.5 知识体系总览

下面这张图,是我自己总结的实时性测试与评估的完整流程。你可以把它当作一个检查清单:

实时性测试与评估知识体系 Cyclictest 工具 线程数 | 优先级 | 间隔 | 循环次数 Min | Avg | Max | 直方图 | 百分位 延迟分布分析 | 最大延迟评估 | 平均延迟评估 | 抖动评估 系统实时性是否满足要求?

嗯,这一章的内容就到这里。实时性测试不是一次性工作,我建议你在项目开发的不同阶段都跑一遍——内核配置完跑一次,驱动写完跑一次,应用层写完再跑一次。每次改动都可能影响实时性,只有持续测试,才能确保系统始终在可控范围内。


专注资料整理