cyclictest 是什么? 看名字应该就能大致猜出来它是一种 test 程序,Cyclictest的维基主页这么介绍它“Cyclictest is a high resolution test program, written by User:Tglx, maintained by User:Clark Williams ”,也就是它是一个高精度的测试程序,Cyclictest 是 rt-tests 下的一个测试工具,也是rt-tests 下使用最广泛的测试工具,一般主要用来测试使用内核的延迟,从而判断内核的实时性。
Debian / Ubuntu 系统下可以直接使用apt-get install rt-tests 来安装cyclictest。
使用Linux最大的好处就是我们可以下载软件的源码,学习、编译以及使用,所以如果使用上述方法直接安装使用,如果你觉得有的问题不懂或者出现问题你也没办法解决,所以从开发者的角度而言,下载安装软件还是下载源码包编译后使用比较好。
# git clone git://git.kernel.org/pub/scm/linux/kernel/git/clrkwllms/rt-tests.git
# cd rt-tests
# git branch testing
# git checkout testing
# git branch
master * testing
# make
编译时我们会遇到缺失numa.h 的错误提示,在此我建议童鞋们安装使用apt-file 来解决此类错误(有了apt-file,遇到这类错误我们就知道如何解决而不是一味的上网找别人的解决方法),主要步骤如下: # sudo apt-get install apt-file // 安装apt-file # apt-file update // 类似于apt-get ,apt-file也需要根据系统配的源来更新一个库 # apt-file search numa.h // 使用apt-file search 搜索我们缺失的文件
libhwloc-dev: /usr/include/hwloc/linux-libnuma.h libnuma-dev: /usr/include/numa.h // 在搜索到的结果中,我们发现这个包叫做 libnuma-dev 应该就是我们需要安装的包 linux-headers-3.2.0-4-amd64: /usr/src/linux-headers-3.2.0-4-amd64/include/config/acpi/numa.h linux-headers-3.2.0-4-amd64: /usr/src/linux-headers-3.2.0-4-amd64/include/config/amd/numa.h
.... # apt-get install libnuma-dev // 使用apt-get 安装libnuma-dev 包
对于Cyclictest的使用我们得先了解它的各个参数的含义,所以在你开始使用之前,请你看一下 cyclictest --help 中提到的各个参数!这将对你使用有很大的帮助。
如果你只是想玩玩这个工具,那么对于维基主页上提到的tglx 使用的测试命令来测测你的电脑性能:
# sudo ./cyclictest -t1 -p 80 -n -i 10000 -l 10000
注:在rt-tests的路径下,我们可以使用 ./cyclictest 来运行cyclictest, 而在别的目录下,我们就需要指定 cyclictest的路径来使用,比如说 /home/long/rt-tests/cyclictest ,或者你也可以直接将 rt-tests的路径下的 cyclictest 拷贝到 /bin/ 下,以后就可以直接使用 cyclictest 而不需要指定路径了!!
比如在我的电脑上,我使用这个命令测试的结果如下:
# /dev/cpu_dma_latency set to 0us policy: fifo: loadavg: 0.38 0.29 0.26 1/381 5595 T: 0 ( 5592) P:80 I:10000 C: 10000 Min: 2 Act: 15 Avg: 15 Max: 195
输出结果含义: T: 0 序号为0的线程 P: 0 线程优先级为0 C: 9397 计数器。线程的时间间隔每达到一次,计数器加1 I: 1000 时间间隔为1000微秒(us) Min: 最小延时(us) Act: 最近一次的延时(us) Avg:平均延时(us) Max: 最大延时(us)
所以我们当前的机器上最小延时为2,平均为15,最大的为 195。
$uname -a // 我们可以使用 “ uname -a ” 看到我们系统目前使用的内核版本 Linux wheezy 3.2.51-trace #8 SMP Thu Nov 21 12:34:04 CST 2013 x86_64 GNU/Linux
$ cat /boot/config-3.2.51-trace |grep CONFIG_PREEMPT_RT // 我们再打开 /boot 下面的当前内核的config信息查看目前这个内核是否打上实时补丁,结果显示并没有。所以在一个普通的内核下测的 Min: 2 Act: 15 Avg: 15 Max: 195 这样的数据算是不错的了!
$ cat /boot/config-3.10.17-trace-rt12 |grep CONFIG_PREEMPT_RT // 而在我 /boot 目录下的另外一个打好实时补丁的内核中 CONFIG_PREEMPT_RT_BASE=y # CONFIG_PREEMPT_RTB is not set CONFIG_PREEMPT_RT_FULL=y // 判断一个内核是否是实时内核,请看config 下有没有此项
我得到的cyclictest 运行结果是这样的:
T: 0 ( 5592) P:80 I:10000 C: 10000 Min: 1 Act: 1 Avg: 2 Max: 9
:-),运行的结果有目共睹,在以后的博客中我会介绍关于Linux 内核的实时补丁。
关于cyclictest 的各个参数具体含义建议大家还是用时间具体看看 cyclictest --help 的信息(参考资料【2】为我的师兄对--help下的每个参数的解释,大家也可以看看!)我这只介绍几个常用的。
-p PRIO --prio=PRIO 最高优先级线程的优先级 使用时方法为: -p 90 / --prio=90 -m --mlockall 锁定当前和将来的内存分配 -c CLOCK --clock=CLOCK 选择时钟 cyclictest -c 1 0 = CLOCK_MONOTONIC (默认) 1 = CLOCK_REALTIME -i INTV --interval=INTV 基本线程间隔,默认为1000(单位为us),下面介绍原理的时候会提到 -l LOOPS --loops=LOOPS 循环的个数,默认为0(无穷个),与 -i 间隔数结合可大致算出整个测试的时间,比如 -i 1000 -l 1000000 ,总的循环时间为1000*1000000=1000000000 us =1000s ,所以大致为16分钟多。 -n --nanosleep 使用 clock_nanosleep -h HISTNUM --histogram=US 在执行完后在标准输出设备上画出延迟的直方图(很多线程有相同的权限)US为最大的跟踪时间限制,这个在下面介绍实例时可以用到,结合gnuplot 可以画出我们测试的结果图。 -q --quiet 使用-q 参数运行时不打印信息,只在退出时打印概要内容,结合-h HISTNUM参数会在退出时打印HISTNUM 行统计信息以及一个总的概要信息。 -f --ftrace ftrace函数跟踪(通常与-b 配套使用,其实通常使用 -b 即可,不使用 -f ) -b USEC --breaktrace=USEC 当延时大于USEC指定的值时,发送停止跟踪。USEC,单位为谬秒(us)。
dslab@wheezy:~$ sudo cyclictest -p 90 - m -c 0 -i 200 -n -h 100 -q -l 1000000
我们使用 -p 90给cyclictest 赋优先级90,使用-m参数锁定内存分配,使用 -c 0指定使用默认的MONOTONIC 时钟, -i 200 指定一个循环为200us,结合 -l 1000000为总共1000000个循环,此外-n 为使用nanosleep 而不是简单的sleep,-q为在运行时不打印即时信息,-h 100 为总共统计100个信息在最后的结果中。 # /dev/cpu_dma_latency set to 0us
---------------------------------------------------(下面都是结束测试/终端测试后打印的信息,这就是 -q 的功效!) # Histogram 000000 000000 000001 111448 -- 延时为1us的在1000000次循环中占111448次(下面每行都是这个意思) 000002 060272 000003 000714 000004 000344 000005 000231 000006 013170 000007 155289 000008 601393 000009 044880 000010 005348 000011 001821 000012 001444 000013 000945 000014 000538 000015 000376 000016 000344 .....
000096 000002 000097 000002 000098 000002 000099 000002 -- 我们使用 -h 100 ,所以在结果中记录了延时为 0us ~ 99us 的次数 # Total: 000999888 # Min Latencies: 00001 -- 最小延时 1 us # Avg Latencies: 00006 -- 平均延时 6us # Max Latencies: 00463 -- 最大延时463 us,那么我们指定histogram = 100也就是只记录了0us~99us的值而最大延时为463 也就是说肯定有很多此延时超过99 us,那么记录到哪了?答案是,没有记录具体的超过99us的延时值,只在下面记录了超过99us 的延时次数(记录在Overflows),以及第几次超过了(记录在Thread 0)。 # Histogram Overflows: 00112 -- 超过99 us的次数 # Histogram Overflow at cycle number: # Thread 0: 02985 06044 06107 08644 08683 12048 18136 30164 33172 33757 36214 48208 54138 58822 61284 83843 83876 86382 92351 92352 96306 108937 108941 111443 117367 129130 129131 146426 155069 155070 159058 161563 171486 184200 186614 209260 211606 221606 223526 223527 234275 234321 236827 241705 241706 246766 266826 296886 321946 334644 336979 337006 359705 367066 384765 392126 412186 437221 442246 462306 472306 484921 487366 497366 507426 509981 512448 512488 522426 542486 567546 587606 610305 617666 635365 637704 637726 660425 672686 692846 710379 710463 717806 735443 737919 742886 760582 763088 767946 785515 785642 788149 793086 806776 808146 810703 813146 835661 835847 838172 # 00012 others //这里记录的是第几次循环的延时超过了99us。