cyclictest原理与源码分析

一、原理

通过定时器测试操作系统的实时性性能。

 (图片来源:知乎)

二、编译源码

源码地址

cyclictest

git clone git://git.kernel.org/pub/scm/linux/kernel/git/clrkwllms/rt-tests.git
cd rt-tests
git checkout -b stable/v1.0 origin/stable/v1.0     
#此为稳定分支,用户还可根据需要切换到最新的devel分支
#安装依赖:libnuma-devel   
#cyclictest的编译会依赖libnuma-devel包,用户可以通过apt-get等方式直接install
#或是下载个rpm解压后然后将需要的两个文件直接拷过去。 解压rpm命令:rpm2cpio *.rpm| cpio -div
make all    
make install

模拟负载:

运行cyclictest前,我们有几点需要注意的地方。首先是短时间的运行cyclictest得出的结果是无意义的,再就是测试系统上没有合适负载的情况下运行cyslictest所得到的延时统计也是无意义的。所以我们最好在待测系统上模拟出负载并运行cyclictest大于24小时统计出延时。关于负载的话,官方在rt-tests源码包中提供了一个名为Hackbench工具可以用来模拟部分类型的负载。以及官方提供了一些模拟负载的脚本:负载脚本

关于负载的模拟,我们需要从CPU、memory、I/O、网络、任务数量、中断等各个方面进行模拟。

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

我这里用的是更强大的stress-ng,大家可自行选择。

举例:

stress-ng -c 24 --cpu-method fft --timerfd-freq 1000000 -t 24h &

//在24个cpu上运行傅里叶变换把cpu拉到100%,然后产生1MHZ的定时器中断,在后台持续运行24小时。

三、源码解析

所分析的源码地址:

https://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git/tree/src/cyclictest

在main函数中创建多个线程,运行timerthread函数。

for (i = 0; i < num_threads; i++) {
	status = pthread_create(&stat->thread, &attr, timerthread, par);
}

 timerthread函数的主体逻辑:

在一个while循环中,sleep(interval); interval值默认是1000us,即1ms。

判断sleep后的时间变量now 与 sleep前的变量next时间的差值

while (!shutdown) {

	uint64_t diff;
	unsigned long diff_smi = 0;
	int sigs, ret;


	switch (par->mode) {
	case MODE_CYCLIC:
	case MODE_SYS_ITIMER:
		sigwait(&sigset, &sigs)
		break;

	case MODE_CLOCK_NANOSLEEP:
		clock_nanosleep(par->clock,TIMER_RELTIME, &interval, NULL);
		break;

	case MODE_SYS_NANOSLEEP:
		nanosleep(&interval, NULL);
		break;
	}
	
	ret = clock_gettime(par->clock, &now);

	if (use_nsecs)
		diff = calcdiff_ns(now, next);
	else
		diff = calcdiff(now, next);

}

 calcdiff函数定义在这里:

https://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git/tree/src/include/rt-utils.h

static inline int64_t calcdiff(struct timespec t1, struct timespec t2)
{
	int64_t diff = USEC_PER_SEC * (long long)((int) t1.tv_sec - (int) t2.tv_sec);
	diff += ((int) t1.tv_nsec - (int) t2.tv_nsec) / 1000;
	return diff;
}

参考:

https://events.static.linuxfound.org/sites/events/files/slides/cyclictest.pdf

(十)cyclictest--(zc7045)实时性能测试及原理_yangteng0210的博客-CSDN博客_cyclictest

实时性测试:cyclictest详解 - 知乎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路边闲人2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值