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)