【Linux】系统实时性测试——cyclictest

发布于:2025-07-14 ⋅ 阅读:(19) ⋅ 点赞:(0)

引言

        随着Linux 内核发展,通过优化内核调度机制和中断响应能力,显著降低系统延迟并提高响应的确定性,使其适用于对时间敏感的工业控制、机器人、自动化、音视频处理等关键领域。它不仅保留了 Linux 强大的软硬件兼容性和开源生态优势,为高精度任务调度提供了可靠的操作系统基础。如何测试linux系统的实时性能,本文提供了一种方式——cyclictest工具。


目录

一、rt-tests安装

二、cyclictest命令

1、cyclictest命令的使用

2、cyclictest参数说明

三、cyclictest测试示例

1、测试环境

2、测试参数

3、结果分析

4、总结 


一、rt-tests安装

rt-tests(Real-Time Tests)是一个用于测试 Linux 实时性能的工具集,它包含多个用于测量系统响应时间、调度延迟、中断处理延迟等关键指标的程序。

cyclictest rt-tests 工具包中的其中一个核心组件。

rt-tests包含的常见的工具:

工具名称 功能说明
cyclictest 最常用的实时性测试工具,通过多线程定时唤醒机制测试系统最大延迟
hrtimer-test 测试 hrtimer 子系统的精度和稳定性
pi-stress 测试优先级继承(Priority Inheritance)机制是否正常工作
sigwaittest 测试信号等待行为的实时性
irqsoffpreemptoff 跟踪关闭中断或抢占的时间点,用于分析延迟来源(需 trace-cmd 配合使用)
  • 在线直接安装

对于基于Debian的发行版(如Ubuntu),可以使用apt-get命令来安装

sudo apt-get update
sudo apt-get install rt-tests
  • 离线源码安装

1)使用git下载rt-tests源码

git clone git://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git

 如在windows下使用get bash下载rt-tests源码

2)将源码包复制到目标设备上。

3)进入rt-tests目录,编译后安装

cd rt-tests
make
sudo make install

二、cyclictest命令

rt-tests 中,cyclictest 是最常被使用的工具之一,很多人口语 中的rt-tests ,实际上就是在说 cyclictest

cyclictest的功能如下:

  • 直观地反映系统最大延迟
  • 支持多线程、绑定 CPU、设置优先级等高级功能
  • 输出包括最小 / 最大 / 平均延迟,以及可选的直方图数据
  • 可用于对比不同内核配置或硬件平台的实时性差异

1、cyclictest命令的使用

注意:cyclic使用时需要使用root权限,可以使用sudo或直接在root用户下执行。

2、cyclictest参数说明

提示:加粗参数项为常用参数。

短选项 长选项 参数 释义
-a --affinity[=CPUSET] [CPUSET] 将线程绑定到特定 CPU 上运行。若未指定,则每个线程按编号绑定到对应核心;若指定了 CPU 集合,则轮询分配。
-A --aligned=USEC USEC 对齐线程唤醒时间,偏移为指定微秒数。
-b --breaktrace=USEC USEC 当延迟超过指定微秒数时发送断点追踪命令。
-c --clock=CLOCK CLOCK 选择使用的时钟源:<br>0 = CLOCK_MONOTONIC(默认)<br>1 = CLOCK_REALTIME
--default-system 不尝试调整系统设置(如电源管理),用于测试未优化状态下的性能。
-d --distance=DIST DIST 设置多个线程之间的间隔距离(单位:微秒),默认值为 500。
-D --duration=TIME TIME 指定测试运行的时间长度。可加后缀 m(分钟)、h(小时)、d(天)。例如:-D 10m 表示运行10分钟。
-F --fifo=<path> <path> 创建一个命名管道,并将统计结果写入该管道。
-h --histogram=US US 输出延迟直方图,最大跟踪延迟为 US 微秒。所有线程使用相同优先级。
-H --histofall=US US 同 -h,但增加一列汇总信息。
--histfile=<path> <path> 将延迟直方图输出到指定文件,而非标准输出。
-i --interval=INTV INTV 设置线程基础间隔时间(单位:微秒),默认为 1000。
--json=FILENAME FILENAME 将最终结果以 JSON 格式写入指定文件。
--laptop 节省电池电量模式运行(实时性较差)。
--latency=PM_QOS PM_QOS 设置电源管理延迟目标值,写入 /dev/cpu_dma_latency 文件。默认为 0。
-l --loops=LOOPS LOOPS 设置循环次数,默认为 0(无限循环)。
--mainaffinity=CPUSET CPUSET 设置主控制线程运行的 CPU,不影响测量线程。
-m --mlockall 锁定当前及未来内存分配,防止交换到磁盘。
-M --refresh_on_max 只有在新的最大延迟出现时才更新屏幕,节省带宽。
-N --nsecs 以纳秒代替微秒显示结果。
-o --oscope=RED RED 示波器模式,减少冗余输出,RED 为压缩比例。
-p --priority=PRIO PRIO 设置最高优先级线程的优先级数值。
--policy=NAME NAME 设置测量线程的调度策略:<br>other / normal / batch / idle / fifo / rr
--priospread 从指定优先级开始依次分配不同优先级给各线程。
-q --quiet 仅在退出时打印摘要信息。
-r --relative 使用相对定时器而非绝对定时器。
-R --resolution 检查时钟分辨率,多次调用 clock_gettime() 并通过 -X 输出列表。
--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。
--smi 启用 SMI(系统管理模式)计数功能。
-t --threads[=NUM] [NUM] 启动与 CPU 数量相同的线程;若指定 NUM,则启动 NUM 个线程。
--tracemark 当 -b 触发的延迟超出阈值时写入 trace mark。
-u --unbuffered 强制不缓冲输出,便于实时处理。
-v --verbose 输出详细统计数据,格式:n:c:v(任务号、计数、值,单位为微秒)。
--dbg_cyclictest 打印调试信息,用于调试 cyclictest 本身。
-x --posix_timers 使用 POSIX 定时器而非 clock_nanosleep。

三、cyclictest测试示例

1、测试环境

        设备:树莓派5B(4G)开发板

        CPU:ARM Cortex-A76 4核心4线程

        内核:Linux raspberrypi 6.12.25+rpt-rpi-2712 #1 SMP PREEMPT

                   Debian 1:6.12.25-1+rpt1 (2025-04-30) aarch64 GNU/Linux

        cyclictest版本:V2.40

2、测试参数

sudo cyclictest -a -t4 -p99 -i1000 -h1000  -l10000

参数解释:

  • -a:自动将四个线程分别绑定到四个CPU核心上。
  • -t4:启动四个线程进行测试。
  • -p99:设置线程的优先级为99,确保它们能够尽可能快地响应。
  • -i1000:设置基础间隔时间为1000微秒(即1毫秒)。
  • -h1000:记录延迟的直方图,最大延迟为1000微秒。
  • -l10000:设置每个线程执行 10,000 次循环后停止,如果不设置默认无限循环。

    3、结果分析

    • /dev/cpu_dma_latency set to 0us:表示系统已禁用节能状态(C-states),以获得更精确的实时性能。
    • policy: fifo:线程使用的是 FIFO 实时调度策略。
    • loadavg:系统的负载平均值(这里非常低,适合测试)。
    字段 含义
    T: 0 线程编号(Thread 0)
    (3642) 线程对应的 Linux 进程 PID
    P:99 线程优先级(FIFO 调度下的优先级等级)
    I:1000 基础间隔时间(单位:微秒)
    C: 10000 已完成的循环次数(即定时器唤醒次数)
    Min: 最小延迟(单位:微秒)
    Act: 当前实际延迟(最新一次测量)
    Avg: 平均延迟
    Max: 最大延迟(整个测试过程中最高的延迟)

    # Histogram 直方图输出

    000000 000000 000000 000000 000000

    000001 000011 000004 000003 000005

    000002 001511 003247 001081 000809

    ......

    直方图数据解析 ,第一列为延迟值(如 0μs、1μs、2μs),后面的数字表示该线程在对应延迟值上出现的次数( 注意是次数,不是延迟时间)。
    Delay (μs) Thread 0 Thread 1 Thread 2 Thread 3
    0 0 0 0 0
    1 11 4 3 5
    2 1511 3247 1081 809
    ... ... ... ... ...
    999 0 0 0 0

    # Total: 000010000 000010000 000010000 000010000  

    每个线程总共执行了 10,000 次循环唤醒任务

    # Min Latencies: 00001 00001 00001 00001

    所有线程的最小延迟都是 1 微秒,非常快速地响应定时器唤醒请求。

    # Avg Latencies: 00003 00002 00003 00002

    每个线程平均延迟为 2或3 微秒。

    # Max Latencies: 00020 00007 00008 00007

    第 0 号线程出现了 20 微秒的最大延迟,其他线程最大延迟都在 7~8 微秒之间。

    # Histogram Overflows: 00000 00000 00000 00000

    # Histogram Overflow at cycle number:

    # Thread 0:

    # Thread 1:

    # Thread 2:

    # Thread 3:

    所有线程都没有发生“直方图溢出”,没有超出1000微秒。后面是统计溢出是的情况,所以为空。

    4、总结 

            这里使用的是树莓派官方的内核镜像,实验配置了线程优先级,锁定内寸页,但没有使用 PREEMPT_RT 实时内核,配置核隔离和关闭不必要的服务和软时钟中断源,对于实时内核来说还有一定优化空间。

            在这样的测试环境下看测试结果,整体良好,最小延迟 1μs,最大延迟 20μs(0号核个别异常点),所有线程的最大延迟都较低,说明 Raspberry Pi 5在这个配置下具备较好的实时性表现。


    网站公告

    今日签到

    点亮在社区的每一天
    去签到