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相关推荐

  1. linux内核时间函数us,linux内核中一个有趣的函数calibrate_delay ZZ

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 34  loops_per_sec &=~loopbit; 35  } 36 /* finally,adjust loops per second ...

  2. Mr. Process的一生-Linux内核的社会视角 (2)启动

    原文地址: http://www.manio.org/cn/startup-of-linux-view-of-society.html 其实这才应该是这一系列文章的第一节,因为这篇文章讲的是盘古开天地 ...

  3. linux 内核 初始化失败,300分求内核初始化及启动中出现的问题,

    我的本本是SHARP PC-AX40型号的, 处理器: Intel Pentium III 700M 内存容量: 128M 内存类型: SDRAM 硬盘容量: 20G 屏幕尺寸: 12.1寸 安装的是 ...

  4. 【内核】linux内核启动流程详细分析【转】

    转自:http://www.cnblogs.com/lcw/p/3337937.html Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件 ...

  5. ARM linux的启动部分源代码简略分析

    ARM linux的启动部分源代码简略分析 以友善之臂的mini2440开发板为平台,以较新的内核linux-2.6.32.7版本为例,仅作说明之用. 当内核映像被加载到RAM之后,Bootloade ...

  6. 动静结合学内核:linux idle进程和init进程浅析

    刘柳 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 + titer1@qq.com 退休的贵族进程 ...

  7. 【内核】linux内核启动流程详细分析

    Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件,包括内核入口ENTRY(stext)到start_kernel间的初始化代码, 主要作用 ...

  8. 【Linux 内核 内存管理】Linux 内核内存布局 ④ ( ARM64 架构体系内存分布 | 内核启动源码 start_kernel | 内存初始化 mm_init | mem_init )

    文章目录 一.ARM64 架构体系内存分布 二.Linux 内核启动源码 start_kernel 三.内存初始化源码 mm_init 四.内存初始化源码 mem_init 一.ARM64 架构体系内 ...

  9. 很好的linux启动说明( bootsect.S、setup.S、head.S)

    bootsect.S,系统引导程序,一般不超过512字节. 在PC系统结构中,线性地址0xA0000以上,即640K以上用于图形接口卡和BIOS自身,640K以下为系统的基本内存.如果配置更多的内存, ...

最新文章

  1. LeetCode简单题之拆炸弹
  2. 9名华人当选,包揽总人数1/6!2017 ACM Fellow名单公布,华人强势亮相
  3. 神奇的LINQ ---可以通过对象来查询数据
  4. 解决:pycharm运行程序时在Python console窗口中运行 һ����ң�������1�����
  5. OpenCV将单通道的Mat转换为三通道的Mat
  6. 11个让你吃惊的 Linux 终端命令
  7. 生成.properties文件(bat文件生成)
  8. 蚂蚁森林用户须知_蚂蚁森林刷能量漏洞(轻松读懂规则)
  9. 20行代码简单python爬虫,爬虫实例
  10. Unity3d笔记——制作简单动画
  11. 八大排序算法详解(通俗易懂)
  12. idea 注释格式化之后回到同一行
  13. 如何解决Kettle读取txt文件时出现的中文乱码问题?
  14. 商络转债上市价格预测
  15. 如何做番茄炖牛腩——hadoop理解
  16. 船舶信息查询网址汇集
  17. 帝国CMS7.5基于es(Elasticsearch)7.x的全文搜索插件
  18. 手把手教你安装Juniper 模拟器
  19. C语言 打印杨辉三角
  20. 网关Gateway过滤器的使用

热门文章

  1. 【死磕 Java 集合】— LinkedTransferQueue源码分析
  2. 深入理解Binder系列 1
  3. 首次接触高通遇到的细节小问题
  4. 深入理解iostat
  5. 深入tornado中的ioLoop
  6. 【STM32CubeMX】教程二_IIC驱动0.96oled屏幕(SSD1306)
  7. 三维实景地图建模技术在智慧城市中的应用
  8. Vue运行报错(building modules 1/1 modules 0 activeevents.js:187 throw er)
  9. 2022年双十一蓝牙耳机选哪款?盘点学生平价蓝牙耳机推荐
  10. 请教关于基于C#移动考勤系统的开发。谢谢!!!