kernel获取毫秒、微妙时间

本文介绍在Linux内核环境下两种获取精确时间的方法,并通过具体测试案例对比了毫秒级、微秒级和纳秒级的时间测量效果,推荐使用do_gettimeofday进行高精度计时。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Kernel: v4.4.159
Device: rk3328
Platform Version: Android 9.0

前言:

有时需要在kernel中测试一个函数或者语句的执行时间,就要获取精确的毫秒、微妙的值。下面记录一下两种获取时间的方法及测试结果:

方式1:(推荐使用)

#include <linux/time.h> //需要包含的头文件
struct timeval tstart;  //结构体
do_gettimeofday(&tstart);//获取时间
//打印秒、微妙值
printk("%s, stime: %lds, utime: %ldus\n"\
		, __func__, tstart.tv_sec, tstart.tv_usec);

方式2:(经测试时间未变,不适用于此场景)

#include <linux/time.h>//需要包含的文件
struct timespec time0 = current_kernel_time();//获取时间
//打印秒、纳秒值
printk("%s, stime: %lds, ntime: %ldns\n",\
			 __func__, time0.tv_sec, time0.tv_nsec);

测试方式1

void test1(void)
{
	struct timeval tstart, tend;
	printk("----------------------------------------------------\n");
	do_gettimeofday(&tstart);
	printk("%s, stime: %lds, utime: %ldus\n", __func__, tstart.tv_sec, tstart.tv_usec);
	printk("%s, before mtime: %ldms\n", __func__, 1000 * tstart.tv_sec + tstart.tv_usec / 1000);
	mdelay(1);//延时1ms
	do_gettimeofday(&tend);
	printk("%s, stime: %lds, utime: %ldus\n", __func__, tend.tv_sec, tend.tv_usec);
	printk("%s, after mtime: %ldms\n", __func__, 1000 * tend.tv_sec + tend.tv_usec / 1000);
	printk("%s, time taken: %ldms\n", __func__, 1000 * (tend.tv_sec - tstart.tv_sec) + (tend.tv_usec - tstart.tv_usec) / 1000);
}

1

void test2(void)
{
	struct timeval tstart, tend;
	printk("----------------------------------------------------\n");
	do_gettimeofday(&tstart);
	printk("%s, stime: %lds, utime: %ldus\n", __func__, tstart.tv_sec, tstart.tv_usec);
	printk("%s, before mtime: %ldus\n", __func__, 1000 * 1000 * tstart.tv_sec + tstart.tv_usec);
	udelay(1);//延时1us
	do_gettimeofday(&tend);
	printk("%s, stime: %lds, utime: %ldus\n", __func__, tend.tv_sec, tend.tv_usec);
	printk("%s, after mtime: %ldus\n", __func__, 1000 * 1000 * tend.tv_sec + tend.tv_usec);
	printk("%s, time taken: %ldus\n", __func__, 1000 * 1000 * (tend.tv_sec - tstart.tv_sec) + (tend.tv_usec - tstart.tv_usec));
}

1

测试方式2

void test3(void)
{
	struct timespec time0, time1;
	printk("----------------------------------------------------\n");
	time0 = current_kernel_time();
	printk("%s, before stime: %lds, ntime: %ldns\n", __func__, time0.tv_sec, time0.tv_nsec);
	mdelay(1);//延时1ms
	time1 = current_kernel_time();
	printk("%s, after stime: %lds, ntime: %ldns\n", __func__, time1.tv_sec, time1.tv_nsec);
	printk("%s, ntime taken: %ldns\n", __func__, time1.tv_nsec - time0.tv_nsec);
}

void test4(void)
{
	struct timespec time0, time1;
	printk("----------------------------------------------------\n");
	time0 = current_kernel_time();
	printk("%s, before stime: %lds, ntime: %ldns\n", __func__, time0.tv_sec, time0.tv_nsec);
	udelay(1);//延时1us
	time1 = current_kernel_time();
	printk("%s, after stime: %lds, ntime: %ldns\n", __func__, time1.tv_sec, time1.tv_nsec);
	printk("%s, ntime taken: %ldns\n", __func__, time1.tv_nsec - time0.tv_nsec);
}

void test5(void)
{
	struct timespec time0, time1;
	printk("----------------------------------------------------\n");
	time0 = current_kernel_time();
	printk("%s, before stime: %lds, ntime: %ldns\n", __func__, time0.tv_sec, time0.tv_nsec);
	ndelay(1);//延时1ns
	time1 = current_kernel_time();
	printk("%s, after stime: %lds, ntime: %ldns\n", __func__, time1.tv_sec, time1.tv_nsec);
	printk("%s, ntime taken: %ldns\n", __func__, time1.tv_nsec - time0.tv_nsec);
}	

1

结论: current_kernel_time用于计时,而不用于性能测量.
它返回的值不是基于实际的定时器,而是基于定时器中断更新的时间值.因此精度取决于定时器中断周期.

转载请注明出处:http://www.wolfnx.com/2019/02/06/KernelGetPreciseTime

作者 : wolfnx
邮箱 : wolfnx@outlook.com
邮箱2 : lostnx@gmail.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值