实时系统实时性测试的方法

注意:运行cyclictest前,我们有几点需要注意的地方。首先是短时间的运行cyclictest得出的结果是无意义的,再就是测试系统上没有合适负载的情况下运行cyslictest所得到的延时统计也是无意义的。所以我们最好在待测系统上模拟出负载并运行cyclictest大于24小时统计出延时。

一.模拟负载
关于负载的模拟,我们需要从CPU、memory、I/O、网络、任务数量、中断等各个方面进行模拟。可使用stress(stress-ng)工具或在rt-tests源码包中提供了一个名为Hackbench工具可以用来模拟部分类型的负载:
https://wiki.linuxfoundation.org/realtime/documentation/howto/tools/worstcaselatency

关于为什么不用真实的负载而是模拟负载,是由于我们真实的使用环境并不一定能触发最大的延时,所以我们通常会制造一个比真实使用的负载大的多的负载去最大可能的触发最大的延时。

stress是Linux系统下的系统压力测试工具,可以测试Linux系统的CPU、内存、磁盘I/O等的负载。

当stress测试CPU时,会不断调用进程,计算随机数的平方根;当测试内存时,会不断调用内存调用malloc和内存释放free函数;当测试磁盘I/O时,会不断调用sync()中断,以测试磁盘I/O。

Stress命令
-c, --cpu N:产生N个进程,每个进程都循环调用sqrt函数产生CPU压力。
-i, --io N:产生N个进程,每个进程循环调用sync将内存缓冲区内容写到磁盘上,产生IO压力。通过系统调用sync刷新内存缓冲区数据到磁盘中,以确保同步。如果缓冲区内数据较少,写到磁盘中的数据也较少,不会产生IO压力。在SSD磁盘环境中尤为明显,很可能iowait总是0,却因为大量调用系统调用sync,导致系统CPU使用率sys 升高。
-m, --vm N:产生N个进程,每个进程循环调用malloc/free函数分配和释放内存。
–vm-bytes B:指定分配内存的大小
–vm-stride B:不断的给部分内存赋值,让COW(Copy On Write)发生
–vm-hang N :指示每个消耗内存的进程在分配到内存后转入睡眠状态N秒,然后释放内存,一直重复执行这个过程
–vm-keep:一直占用内存,区别于不断的释放和重新分配(默认是不断释放并重新分配内存)
-d, --hdd N:产生N个不断执行write和unlink函数的进程(创建文件,写入内容,删除文件)
–hdd-bytes B:指定文件大小

–hdd-noclean:不要将写入随机ASCII数据的文件Unlink
-t, --timeout N:在N秒后结束程序
–backoff N:等待N微秒后开始运行
-q, --quiet:程序在运行的过程中不输出信息
-n, --dry-run:输出程序会做什么而并不实际执行相关的操作
–version:显示版本号
-v, --verbose:显示详细的信息

1.正常

2.压力
测试场景
1)cpu密集型
stress 消耗 CPU 资源的方式是通过调用 sqrt 函数计算由 rand 函数产生的随机数的平方根实现的。下面的命令会产生 2个这样的进程执行600s:
stress --cpu 2 --timeout 600

2)IO测试
下面的命令产生 2 个进程,每个进程都反复调用 sync 函数将内存上的内容写到硬盘上,执行60s:
stress --io 2 --timeout 60

3)Memory测试
新增4个内存分配进程,每次每个进程分配大小730M ,分配后不释放,长期保持测试
stress --vm 4 --vm-bytes 730M --vm-keep

–vm-keep
一直占用内存,区别于不断的释放和重新分配(默认是不断释放并重新分配内存)。
–vm-hang N
指示每个消耗内存的进程在分配到内存后转入睡眠状态 N 秒,然后释放内存,一直重复执行这个过程。
–vm-keep 和 --vm-hang 都可以用来模拟只有少量内存的机器,但是指定它们时 CPU 的使用情况是不一样的。
stress --vm 2 --vm-bytes 1G --vm-hang 100 --timeout 100

4)磁盘及I/O测试
新增6个I/O进程,1个写进程,每次写1000M文件块,测试100秒
stress --io 6 -d 1 --hdd-bytes 1000M -t 100
下面的命令创建一个进程不断的在磁盘上创建 10M 大小的文件并写入内容:
stress -d 1 --hdd-bytes 10M

除了单独指定某一类的选项,还可以同时执行多个类型的任务,比如产生 3 个 CPU 进程、3 个 IO 进程、2 个10M 的 vm 进程,并且每个 vm 进程中不循环分配释放内存:
stress --cpu 3 --io 3 --vm 2 --vm-bytes 10M --vm-keep

二.实时性测试

根据将在系统上执行的最终应用程序,Cyclictest测量的延迟可能有点乐观。这是因为Cyclictest度量线程使用nanosleep,因此它们实际上具有RT用户空间任务所能拥有的最短的唤醒时间。当使用nanosleep时,Cyclictest线程计时器到期路径直接在硬中断上下文中执行,不需要额外的间接。因此,如果一个应用程序任务的唤醒没有在硬中断上下文中完成(例如,线程中断上下文中),由于额外的间接级别,在相同的情况下,应用程序任务将经历比Cyclictest测量线程更长的唤醒延迟。

cyclictest

-a [NUM] --affinity run thread #N on processor #N, if possible
with NUM pin all threads to the processor NUM
-b USEC --breaktrace=USEC send break trace command when latency > USEC
-B --preemptirqs both preempt and irqsoff tracing (used with -b)
-c CLOCK --clock=CLOCK select clock
0 = CLOCK_MONOTONIC (default)
1 = CLOCK_REALTIME
-C --context context switch tracing (used with -b)
-d DIST --distance=DIST distance of thread intervals in us default=500
-E --event event tracing (used with -b)
-f --ftrace function trace (when -b is active)
-i INTV --interval=INTV base interval of thread in us default=1000
-I --irqsoff Irqsoff tracing (used with -b)
-l LOOPS --loops=LOOPS number of loops: default=0(endless)
-m --mlockall lock current and future memory allocations
-n --nanosleep use clock_nanosleep
-N --nsecs print results in ns instead of ms (default ms)
-o RED --oscope=RED oscilloscope mode, reduce verbose output by RED
-O TOPT --traceopt=TOPT trace option
-p PRIO --prio=PRIO priority of highest prio thread
-P --preemptoff Preempt off tracing (used with -b)
-q --quiet print only a summary on exit
-r --relative use relative timer instead of absolute
-s --system use sys_nanosleep and sys_setitimer
-T TRACE --tracer=TRACER set tracing function
configured tracers: unavailable (debugfs not mounted)
-t --threads one thread per available processor
-t [NUM] --threads=NUM number of threads:
without NUM, threads = max_cpus
without -t default = 1
-v --verbose output values on stdout for statistics
format: n:c:v n=tasknum c=count v=value in us
-D --duration=t specify a length for the test run
default is in seconds, but ‘m’, ‘h’, or ‘d’ maybe add
ed
to modify value to minutes, hours or days
-h --histogram=US dump a latency histogram to stdout after the run
US is the max time to be be tracked in microseconds
-w --wakeup task wakeup tracing (used with -b)
-W --wakeuprt rt task wakeup tracing (used with -b)

基本参数的使用:
下面是我在smp架构的机器上进行测试的一组参数
./cyclictest -S -p 95 -d 0 -i 1000 -D 48h -m -n
上面这组指定了-S,所以每个core分配了一个thread,读者使用时也可以去掉-S,自己指定threads数量和设置亲和性,如下:
./cyclictest -p 95 -t 16 -d 500 -i 1000 -D 48h -m -a -n
Tips: 我只在smp架构的机器上进行了测试,这里只说明smp的参数配置,numa架构略过。
关于如何选择参数,官方有个说明文档:
Number and affinity of measuring threads (–threads, –affinity)
Thread wake-up interval (–interval, –distance)
Thread real-time priority (–priority)
Test duration
Prevent Cyclictest pages from being paged out of memory (–mlockall)
Use clock_nanosleep( ) (–nanosleep)
输出参数的使用:
我比较常用的参数有-h和-q。-h用来输出直方图,-q用来在测试完成后再打印结果。
cyclictest的输出可以绘制成直方图,详细步骤参考:
https://www.osadl.org/Create-a-latency-plot-from-cyclictest-hi.bash-script-for-latency-plot.0.html
追踪参数的使用:
关于tracing events的选项,我简单做了下试验,命令行如下。当latency大于100时,cyclictest会自动退出,然后我们cat /sys/kernel/debug/tracing/trace |grep cyclictest可以看到已经抓取到的context_switch事件。
//使用function_graph tracer追踪当latency超过100时,已经发生的context_switch事件。
cyclictest -S -p 95 -t -i 1000 -D 1h -m -d 1000 -b 100 --context --event --ftrace -T function_graph
特别注意:traceing的过程中我们通常使用–ftrace,而ftrace的原理是通过在函数入口和出口产生异常,这样得到latency结果包含ftrace的overhead,通常会是几十微秒的数量级,所以在设置-b参数时,我们需要预估一下ftrace带来的overhead。

Cyclictest测量结果含义:

缩写 标签 描述
T 线程 线程索引和线程ID
P 优先级 实时线程优先级
I 间隔 延迟测量线程的预期唤醒周期(微秒)
C 计数 测量延迟的次数,即迭代计数
Min 最小值 测量的最小延迟(微秒)
Act 实际值 在最近完成的迭代中测量的延迟(微秒)
Max 最大值 测量的最大延迟(微秒)

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值