linux内核calibrate_delay函数实现分析

这篇博客详细分析了Linux内核中`calibrate_delay`函数的实现过程,包括如何通过二分法逼近计算`loops_per_jiffy`,以达到精确测量处理器速度的目的。在MIPS架构下,由于特定条件,函数采用了不同的计算策略。
公司使用的是mips处理器,每秒钟jiffs是250个,内核变量HZ值就是250,由此我引发一个疑问,一个jiffs时钟中断耗时4ms,没法做到毫秒微妙甚至纳秒的精度,那么内核延时函数mdelay udelay ndelya是如何实现的呢,于是研究了一下,就找到了linux内核中一个有趣的函数calibrate_delay()。 
calibrate_delay()函数可以计算出cpu在一秒钟内执行了多少次一个极短的循环,最终计算出来的值赋给变量loop_per_jiffs,经过处理后得到BogoMIPS 值,Bogo是Bogus(伪)的意思,MIPS是millions of instructions per second(百万条指令每秒)的缩写。这样我们就知道了其实这个函数是linux内核中一个cpu性能测试函数。对于内核延时函数,关键点就是loop_per_jiffs,udelay函数就是利用这个变量计算出自己延时所需要的短循环。来实现微秒级延时。由于内核对这个数值的要求不高,所以内 核使用了一个十分简单而有效的算法用于得到这个值。如果你想了解自己机器的BogoMIPS,你可以察看 /proc/cpuinfo文件中的bogomips。让我们一起来看看 calibrate_delay函数是怎么完成工作的。 
下面是2.6.21版本内核下calibrate_delay的源代码,这个函数是在内核启动函数start_kernel中调用。
108 /*
109  * This is the number of bits of precision for the loops_per_jiffy.  Each
110  * bit takes on average 1.5/HZ seconds.  This (like the original) is a little
111  * better than 1%
112  */
113 #define LPS_PREC 8
114 
115 void __devinit calibrate_delay(void)
116 {
117     unsigned long ticks, loopbit;
118     int lps_precision = LPS_PREC;
119 
120     if (preset_lpj) {
121         loops_per_jiffy = preset_lpj;
122         printk("Calibrating delay loop (skipped)... "
123             "%lu.%02lu BogoMIPS preset\n",
124             loops_per_jiffy/(500000/HZ),
125             (loops_per_jiffy/(5000/HZ)) % 100);
126     } else if ((loops_per_jiffy = calibrate_delay_direct()) != 0) {
127         printk("Calibrating delay using timer specific routine..
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值