Cyclictest工具
Cyclictest通过准确地、反复地度量线程的预期唤醒时间和它实际唤醒的时间之间的差异,以便提供关于系统延迟的统计信息。它可以测量实时系统中由硬件、固件和操作系统引起的延迟。
最初的测试是由Thomas Gleixner (tglx)编写的,但是后来有几个人贡献了修改。Cyclictest目前由Clark Williams和John Kacur维护,是rt-tests测试套件的一部分。
应用案例
Cyclictest最常用于对实时系统进行基准测试。它是评价实时系统相对性能最常用的工具之一。下面列出了一些使用Cyclictest所做的性能测试场景,以及Cyclictest的其他一些应用场景。
- 系统基准测试:RTEval,最坏情况的延迟测试场景
- 使用跟踪的延迟调试
- 近似应用程序性能
OSADL(开源自动化开发实验室)使用Cyclictest持续地监视几个系统的延迟。关于该项目以及他们使用的特定Cyclictest选项的更多细节可以在OSADL网站上找到。
技术说明
为了度量延迟,Cyclictest运行一个非实时的主线程(调度类SCHED_OTHER),它启动一个具有定义的实时优先级的定义数量的度量线程(调度类SCHED_FIFO)。测量线程被一个即将过期的定时器(循环报警)以一个定义的间隔周期性唤醒。随后,计算已编程的唤醒时间和有效唤醒时间之间的差异,并通过共享内存移交给主线程。主线程跟踪延迟值并打印最小、最大和平均延迟。
执行测试
Cyclictest必须使用sudo运行,或者作为实时组的成员运行。下面是一个与大多数SMP实时系统相关的测试用例:
# cyclictest --mlockall --smp --priority=80 --interval=200 --distance=0
上面的选项并不适用于所有系统的所有情况。Cyclictest Test Design页面详细介绍了如何选择正确的选项来测量给定系统上的特定延迟。此外,cyclictest -h提供了不同程序选项的快速描述,更详细的解释可以通过运行man ./src/cyclictest/cyclictest找到。8从根目录下的rt-tests文件。
不推荐在没有任何选项的情况下运行Cyclictest,因为它不一定会度量任何有用的东西。如果没有参数,Cyclictest将创建一个线程,其预期唤醒周期为1毫秒。
测试结果
下面是一个Cyclictest结果的示例:
T: 0 (821) P: 80 I: 200 C: 518063 Min: 1 Act: 1 Avg: 1 Max: 15
T: 1 (822) P: 80 I: 200 C: 518050 Min: 1 Act: 2 Avg: 1 Max: 23
这些结果是通过在运行RT补丁4.9内核版本的2 CPU机器上短时间运行上面执行部分给出的示例命令获得的。由于格式原因,上述结果中的空格已被更改。
下表是对结果中缩写标签的描述:
缩写 | 标签 | 描述 |
---|---|---|
T | 线程 | 线程索引和线程ID |
P | 优先级 | 实时线程优先级 |
I | 间隔 | 延迟测量线程的预期唤醒周期(微秒) |
C | 计数 | 测量延迟的次数,即迭代计数 |
Min | 最小值 | 测量的最小延迟(微秒) |
Act | 实际值 | 在最近完成的迭代中测量的延迟(微秒) |
Max | 最大值 | 测量的最大延迟(微秒) |
用于表示延迟值的默认单位是微秒(us),但是可以使用-nsecs选项将其更改为纳秒。
柱状图
程序选项-histogram和-histofall可用于在测试结束时将延迟的直方图输出到stdout。这些选项的更详细描述可以在帮助菜单(-help)或Cyclictest手册页中找到。或者,可以使用OSADL脚本运行Cyclictest,并使用生成的直方图数据生成延迟图。在运行脚本之前,应该修改它,以便传递给Cyclictest的选项与预期的测试用例匹配。关于这一点的更多细节可以在下面的测试设计部分找到。
分析
结果中最重要的值是检测到的最大延迟,因为这个值可以给出评估情况下的最坏情况的延迟长度。这些结果总是应该仔细评估,因为最大测量值不一定代表系统的最坏情况。关于为什么应该严格解释结果的更多细节可以通过Cyclictest Test Design页面和下面的限制部分找到。
不可能为延迟长度指定一个普遍适用的推荐限制。应该根据系统对所测量的延迟的时间需求来分析Cyclictest结果。例如,如果测量了特定实时任务的延迟,那么应该将结果与该特定任务的时间需求进行比较。需求将决定系统中观察到的延迟是可接受的还是太长。
预期结果
要了解被测试系统与其他实时平台的对比情况,一种有趣的方法是使用OSADL用于对实时QA Farm中的系统进行基准测试的相同选项运行Cyclictest,然后将结果与被测试系统产生的结果进行比较。系统使用的确切Cyclictest命令在系统延迟图旁边指定。还可以看到当前正在测试的所有实时设备的组合结果的延迟图。
与运行负载、使用各种Cyclictest参数并运行不同实时和非实时内核的其他系统的结果进行比较也会很有趣。这些结果给出了延迟的量级的一般概念。它们还显示了不同的测试条件和参数对Cyclictest结果的影响。
测试设计
Cyclictest可用于检测在许多不同的系统和情况下发生的延迟。然而,必须谨慎地设计测试,因为不度量预期要度量的延迟是相对容易的。测试设置和传递给Cyclictest的参数都需要根据需要评估延迟的特定情况谨慎选择。如果没有仔细考虑这些元素,那么Cyclictest结果将不能准确地表示在这种情况下发生的延迟。
局限性
根据将在系统上执行的最终应用程序,Cyclictest测量的延迟可能有点乐观。这是因为Cyclictest度量线程使用nanosleep,因此它们实际上具有RT用户空间任务所能拥有的最短的唤醒时间。当使用nanosleep时,Cyclictest线程计时器到期路径直接在硬中断上下文中执行,不需要额外的间接。因此,如果一个应用程序任务的唤醒没有在硬中断上下文中完成(例如,线程中断上下文中),由于额外的间接级别,在相同的情况下,应用程序任务将经历比Cyclictest测量线程更长的唤醒延迟。在这种情况下,即使延迟开始的时间正好是Cyclictest线程打算执行的时间,并且线程受到整个延迟时间的影响,Cyclictest线程的延迟度量仍然是乐观的。