linux calibrate_delay
https://blog.csdn.net/chenliang0224/article/details/78704823
1.内核启动信息
console [ttyS0] enabled
Calibrating delay loop… 148.88 BogoMIPS (lpj=744448)
pid_max: default: 32768 minimum: 301
2.BogoMIPS
BogoMIPS (Bogo–Bogus–伪的,MIPS–millions of instruction per second) 按照字面的解释是“不太真实的MIPS”。之所以不太真实,那是因为其计算方法并不十分精确。BogoMIPS的值在系统系统时,在一闪而过的启动信息里可以看到;也可以dmesg看到;还可以通过查看/proc/cpuifo看到。BogoMIPS 的值是 linux 内核通过在一个时钟节拍里不断的执行循环指令而估算出来,它实际上反应了 CPU 的速度。
3.calibrate_delay()
路径:linux-3.10.x\init\main.c–>start_kernel–>calibrate_delay
void __cpuinit calibrate_delay(void)
{
unsigned long lpj;
static bool printed;
int this_cpu = smp_processor_id();
if (per_cpu(cpu_loops_per_jiffy, this_cpu)) {lpj = per_cpu(cpu_loops_per_jiffy, this_cpu);if (!printed)pr_info("Calibrating delay loop (skipped) ""already calibrated this CPU");
} else if (preset_lpj) {lpj = preset_lpj;if (!printed)pr_info("Calibrating delay loop (skipped) ""preset value.. ");
} else if ((!printed) && lpj_fine) {lpj = lpj_fine;pr_info("Calibrating delay loop (skipped), ""value calculated using timer frequency.. ");
} else if ((lpj = calibrate_delay_is_known())) {;
} else if ((lpj = calibrate_delay_direct()) != 0) {if (!printed)pr_info("Calibrating delay using timer ""specific routine.. ");
} else {if (!printed)pr_info("Calibrating delay loop... ");lpj = calibrate_delay_converge();
}
per_cpu(cpu_loops_per_jiffy, this_cpu) = lpj;
if (!printed)pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n",lpj/(500000/HZ),(lpj/(5000/HZ)) % 100, lpj);loops_per_jiffy = lpj;
printed = true;
}
BogoMIPS计算的核心函数:
static unsigned long __cpuinit calibrate_delay_converge(void)
{
/* First stage - slowly accelerate to find initial bounds */
unsigned long lpj, lpj_base, ticks, loopadd, loopadd_base, chop_limit;
int trials = 0, band = 0, trial_in_band = 0;
lpj = (1<<12); //1<<12=4096/* wait for "start of" clock tick */
ticks = jiffies;
while (ticks == jiffies) //等待下一个时钟节拍; /* nothing */
/* Go .. */
ticks = jiffies;
do {if (++trial_in_band == (1<<band)) { //首次进入do{...}while(x)时if条件成立,初始化band=1和trial_in_band=0++band;trial_in_band = 0;}__delay(lpj * band);trials += band;
} while (ticks == jiffies); //一个时钟节拍内的循环次数
/** We overshot, so retreat to a clear underestimate. Then estimate* the largest likely undershoot. This defines our chop bounds.*/
trials -= band; //去除上面do{...}while(x)里循环的最后一次,因为最后一次时钟节拍已经变更,所以不能统计到里面
loopadd_base = lpj * band; //上面do{...}while(x)最后一次循环所需的时间,也是下一个时钟节拍的起始值
lpj_base = lpj * trials; //一个时钟节拍需要的时间
recalibrate:
lpj = lpj_base; //一个时钟节拍需要的时间
loopadd = loopadd_base; //上面do{…}while(x)最后一次循环所需的时间,也是下一个时钟节拍的起始值
/** Do a binary approximation to get lpj set to* equal one clock (up to LPS_PREC bits)*/
chop_limit = lpj >> LPS_PREC; //用于控制循环计算的次数,一个时钟节拍分频/2^8, 2^8=256
while (loopadd > chop_limit) { //采用二分法的方式,无限靠近真值, 下一个时钟节拍的首次值 > 一个时钟节拍内256分频后的值,通过分析该while循环意思应该是要循环256次lpj += loopadd;ticks = jiffies;while (ticks == jiffies); /* nothing */ticks = jiffies;__delay(lpj);if (jiffies != ticks) /* longer than 1 tick */lpj -= loopadd; //时钟滴答切换,徐去除最后一次值,这里的loopadd由上面计算出,即是滴答更新时,上一次滴答的最后一次值loopadd >>= 1; //将时钟滴答切换时,上一次的时钟滴答最后一次的值进行“二分法”,已达到精确值
}
/** If we incremented every single time possible, presume we've* massively underestimated initially, and retry with a higher* start, and larger range. (Only seen on x86_64, due to SMIs)*///若每一次都是递增的(可能低估了lpj),则需要使用较大的初值和步幅
if (lpj + loopadd * 2 == lpj_base + loopadd_base * 2) {lpj_base = lpj;loopadd_base <<= 2;goto recalibrate;
}return lpj;
}
根据报文中lpj=744448,Calibrating delay loop… 148.88 BogoMIPS (lpj=744448)
作者:chenliang0224
来源:CSDN
原文:https://blog.csdn.net/chenliang0224/article/details/78704823
版权声明:本文为博主原创文章,转载请附上博文链接!
linux calibrate_delay相关推荐
- linux内核时间函数us,linux内核中一个有趣的函数calibrate_delay ZZ
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 34 loops_per_sec &=~loopbit; 35 } 36 /* finally,adjust loops per second ...
- Mr. Process的一生-Linux内核的社会视角 (2)启动
原文地址: http://www.manio.org/cn/startup-of-linux-view-of-society.html 其实这才应该是这一系列文章的第一节,因为这篇文章讲的是盘古开天地 ...
- linux 内核 初始化失败,300分求内核初始化及启动中出现的问题,
我的本本是SHARP PC-AX40型号的, 处理器: Intel Pentium III 700M 内存容量: 128M 内存类型: SDRAM 硬盘容量: 20G 屏幕尺寸: 12.1寸 安装的是 ...
- 【内核】linux内核启动流程详细分析【转】
转自:http://www.cnblogs.com/lcw/p/3337937.html Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件 ...
- ARM linux的启动部分源代码简略分析
ARM linux的启动部分源代码简略分析 以友善之臂的mini2440开发板为平台,以较新的内核linux-2.6.32.7版本为例,仅作说明之用. 当内核映像被加载到RAM之后,Bootloade ...
- 动静结合学内核:linux idle进程和init进程浅析
刘柳 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 + titer1@qq.com 退休的贵族进程 ...
- 【内核】linux内核启动流程详细分析
Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件,包括内核入口ENTRY(stext)到start_kernel间的初始化代码, 主要作用 ...
- 【Linux 内核 内存管理】Linux 内核内存布局 ④ ( ARM64 架构体系内存分布 | 内核启动源码 start_kernel | 内存初始化 mm_init | mem_init )
文章目录 一.ARM64 架构体系内存分布 二.Linux 内核启动源码 start_kernel 三.内存初始化源码 mm_init 四.内存初始化源码 mem_init 一.ARM64 架构体系内 ...
- 很好的linux启动说明( bootsect.S、setup.S、head.S)
bootsect.S,系统引导程序,一般不超过512字节. 在PC系统结构中,线性地址0xA0000以上,即640K以上用于图形接口卡和BIOS自身,640K以下为系统的基本内存.如果配置更多的内存, ...
最新文章
- LeetCode简单题之拆炸弹
- 9名华人当选,包揽总人数1/6!2017 ACM Fellow名单公布,华人强势亮相
- 神奇的LINQ ---可以通过对象来查询数据
- 解决:pycharm运行程序时在Python console窗口中运行 һ����ң�������1�����
- OpenCV将单通道的Mat转换为三通道的Mat
- 11个让你吃惊的 Linux 终端命令
- 生成.properties文件(bat文件生成)
- 蚂蚁森林用户须知_蚂蚁森林刷能量漏洞(轻松读懂规则)
- 20行代码简单python爬虫,爬虫实例
- Unity3d笔记——制作简单动画
- 八大排序算法详解(通俗易懂)
- idea 注释格式化之后回到同一行
- 如何解决Kettle读取txt文件时出现的中文乱码问题?
- 商络转债上市价格预测
- 如何做番茄炖牛腩——hadoop理解
- 船舶信息查询网址汇集
- 帝国CMS7.5基于es(Elasticsearch)7.x的全文搜索插件
- 手把手教你安装Juniper 模拟器
- C语言 打印杨辉三角
- 网关Gateway过滤器的使用
热门文章
- 【死磕 Java 集合】— LinkedTransferQueue源码分析
- 深入理解Binder系列 1
- 首次接触高通遇到的细节小问题
- 深入理解iostat
- 深入tornado中的ioLoop
- 【STM32CubeMX】教程二_IIC驱动0.96oled屏幕(SSD1306)
- 三维实景地图建模技术在智慧城市中的应用
- Vue运行报错(building modules 1/1 modules 0 activeevents.js:187 throw er)
- 2022年双十一蓝牙耳机选哪款?盘点学生平价蓝牙耳机推荐
- 请教关于基于C#移动考勤系统的开发。谢谢!!!