实时性测试指南与结果解读
概要:本文介绍了在不同负载条件下使用 cyclictest 工具对 Linux 系统进行实时性测试的方法,涵盖测试环境配置、命令详解及测试结果的解读,特别强调了在压力测试下进行评估的重要性,并提供了一个非实时内核下的测试结果示例。
1. 测试环境说明
Linux 实时性测试通常包括两种环境:
- 空载测试:开机后不运行非必要软件进行测试。
- 压力测试:使用 stress-ng 工具生成系统负载进行测试。
在负载条件下测试 Linux 实时系统远比在空载条件下测试更具参考价值。在空载(idle)状态下,系统几乎所有的资源(CPU、内存带宽、缓存、总线等)都专属于实时任务,可能导致结果过于理想。
空载测试的主要作用:
- 作为性能“基线”或“下限”。
- 验证测量工具和方法的有效性。
- 如果空载时延迟都很大,说明系统配置或测试方法存在问题。
2. 测试步骤
以 RK3588 平台为例:
2.1 生成负载(压力测试)
stress-ng -c 8 --io 2 --vm 1 --vm-bytes 1024M --timeout 1000000s
注意:测试过程中需注意散热问题。
2.2 执行 cyclictest 测试命令
cyclictest -c 0 -m -t 8 -p 99
可加入 -D 选项指定测试时长,例如:
cyclictest -c 0 -m -t 8 -p 99 -D 600
-D 600表示测试 600 秒(即 10 分钟)。
建议测试时长一般设置为 2 小时,以获得更稳定的数据。
3. 命令解读
cyclictest -c 0 -m -t 8 -p 99
| 选项 | 含义 | 说明 |
|---|---|---|
-c 0 |
时钟选择 | 使用 CLOCK_MONOTONIC,单调递增,不受系统时间调整影响 |
-m |
内存锁定 | 锁定当前和未来内存分配,避免页面交换导致的延迟 |
-t 8 |
线程数量 | 创建 8 个测试线程 |
-p 99 |
线程优先级 | 设置线程优先级为 99(Linux 实时优先级范围为 1-99,99 为最高) |
-D 600 |
测试时长 | 可选参数,表示测试持续时间为 600 秒(10 分钟) |
4. 测试结果示例解读(非实时内核)
以下为在非实时内核下运行 cyclictest 的测试结果:
root@user:~# cyclictest -c 0 -m -t 8 -p 99 -D 600
WARN: cyclictest was not built with the numa option
# /dev/cpu_dma_latency set to 0us
policy: fifo: loadavg: 13.27 11.86 7.28 13/588 2516
T: 0 ( 2475) P:99 I:1000 C: 599944 Min: 2 Act: 3 Avg: 5 Max: 3059
T: 1 ( 2476) P:99 I:1500 C: 399998 Min: 2 Act: 3 Avg: 5 Max: 1652
T: 2 ( 2477) P:99 I:2000 C: 299995 Min: 2 Act: 4 Avg: 5 Max: 2319
T: 3 ( 2478) P:99 I:2500 C: 239991 Min: 2 Act: 3 Avg: 5 Max: 2554
T: 4 ( 2479) P:99 I:3000 C: 199992 Min: 2 Act: 3 Avg: 4 Max: 1595
T: 5 ( 2480) P:99 I:3500 C: 171420 Min: 2 Act: 5 Avg: 5 Max: 2573
T: 6 ( 2481) P:99 I:4000 C: 149990 Min: 2 Act: 3 Avg: 4 Max: 69
T: 7 ( 2482) P:99 I:4500 C: 133327 Min: 2 Act: 6 Avg: 5 Max: 930
4.1 各列含义
| 列名 | 含义 |
|---|---|
| T | 线程编号 |
| I | 中断间隔(μs) |
| C | 循环次数 |
| Min | 最小延迟(μs) |
| Act | 当前延迟(μs) |
| Avg | 平均延迟(μs) |
| Max | 最大延迟(μs) |
4.2 示例说明(以 T:0 为例)
T: 0 I:1000 C: 599944 Min: 2 Act: 3 Avg: 5 Max: 3059
- 线程 0
- 每 1000 微秒中断一次
- 执行了 599944 次循环
- 最小延迟为 2 微秒,平均为 5 微秒,最大延迟达到 3059 微秒
可以看到,某些线程出现了毫秒级别(ms)的最大延迟,说明非实时内核在负载下存在较大延迟波动。
5. 附录:cyclictest 帮助文档翻译
| 短选项 | 长选项 | 参数 | 描述 |
|---|---|---|---|
-a [NUM] |
--affinity |
[NUM] |
如果可能,将线程#N运行在处理器#N上;使用NUM时将所有线程固定到处理器NUM |
-A USEC |
--aligned=USEC |
USEC |
将线程唤醒对齐到特定偏移量 |
-b USEC |
--breaktrace=USEC |
USEC |
当延迟 > USEC时发送断点跟踪命令 |
-c CLOCK |
--clock=CLOCK |
CLOCK |
选择时钟:0 = CLOCK_MONOTONIC(默认),1 = CLOCK_REALTIME |
-d DIST |
--distance=DIST |
DIST |
线程间隔距离(微秒),默认=500 |
-D |
--duration=TIME |
TIME |
指定测试运行时长,可附加’m’、’h’、’d’指定分钟、小时或天数 |
--latency=PM_QOS |
PM_QOS |
将PM_QOS写入/dev/cpu_dma_latency | |
-F |
--fifo=<path> |
<path> |
在指定路径创建命名管道并写入统计信息 |
-h |
--histogram=US |
US |
运行后在stdout输出延迟直方图,US是要跟踪的最大延迟时间(微秒),此选项以相同优先级运行所有线程 |
-H |
--histofall=US |
US |
与-h相同,但增加额外的摘要列 |
--histfile=<path> |
<path> |
将延迟直方图输出到指定路径而非stdout | |
-i INTV |
--interval=INTV |
INTV |
线程基准间隔(微秒),默认=1000 |
-l LOOPS |
--loops=LOOPS |
LOOPS |
循环次数,默认=0(无限循环) |
--laptop |
运行时节省电量,这会降低实时性结果但不会快速耗尽电池 | ||
-m |
--mlockall |
锁定当前和未来的内存分配 | |
-M |
--refresh_on_max |
直到达到新的最大延迟时才更新屏幕,适用于低带宽情况 | |
-N |
--nsecs |
以纳秒而非微秒打印结果(默认微秒) | |
-o RED |
--oscope=RED |
RED |
示波器模式,按RED减少详细输出 |
-p PRIO |
--priority=PRIO |
PRIO |
最高优先级线程的优先级 |
--policy=NAME |
NAME |
测量线程的调度策略,NAME可以是:other、normal、batch、idle、fifo或rr | |
--priospread |
从指定值开始扩展优先级级别 | ||
-q |
--quiet |
仅在退出时打印摘要 | |
-r |
--relative |
使用相对定时器而非绝对定时器 | |
-R |
--resolution |
检查时钟分辨率,多次调用clock_gettime(),使用-X报告clock_gettime()值列表 | |
--secaligned [USEC] |
[USEC] |
将线程唤醒对齐到下一个整秒并可选择应用偏移量 | |
-s |
--system |
使用sys_nanosleep和sys_setitimer | |
-S |
--smp |
标准SMP测试:选项-a -t且所有线程优先级相同 | |
--spike=<trigger> |
<trigger> |
记录所有大于触发值的尖峰 | |
--spike-nodes=[num of nodes] |
[num of nodes] |
可记录的最大尖峰数,未指定时默认为1024 | |
-t |
--threads |
每个可用处理器一个线程 | |
-t [NUM] |
--threads=NUM |
[NUM] |
线程数:无NUM时线程数=max_cpus,无-t时默认=1 |
--tracemark |
当超过-b延迟时写入跟踪标记 | ||
-u |
--unbuffered |
强制无缓冲输出以便实时处理 | |
-v |
--verbose |
在stdout输出统计值,格式:n:c:v n=任务编号 c=计数 v=值(微秒) | |
--dbg_cyclictest |
打印对调试cyclictest有用的信息 | ||
-x |
--posix_timers |
使用POSIX定时器而非clock_nanosleep |
留下评论