BogoMips

BogoMips ("bogus"與MIPS，伪MIPS) 是一种衡量CPU速度的不科学方法。当计算机内核启动时，将执行一个计数循环。

对于特定的CPU，BogoMips可用来查看它是否个合适的值。它的时钟频率和它潜在的CPU缓存。但是它不可在不同的CPU间进行比较演示。

 合适的BogoMips比率 
作为一个参考向导，BogoMips可以用下列的表格进行预计算。给出的比率是以应用到LINUX版本的CPU作为例子。指数是指其它CPU同Intel 386DX CPU的BogoMips/clock speed比率.
CPU比率指数Intel 8088 clock * 0.0040.02Intel/AMD 386SX clock * 0.140.8Intel/AMD 386DX clock * 0.181 (definition)Motorola 68030clock * 0.251.4Cyrix/IBM 486clock * 0.341.8Intel Pentiumclock * 0.402.2Intel 486 clock * 0.502.8AMD 5x86clock * 0.502.8MIPS R4000/R4400clock * 0.502.8ARM9clock * 0.502.8Motorola 8081clock * 0.653.6Motorola 68040clock * 0.673.7PowerPC 603clock * 0.673.7Intel StrongARMclock * 0.663.7NexGen Nx586clock * 0.754.2PowerPC 601clock * 0.844.7Alpha 21064/21064Aclock * 0.995.5Alpha 21066/21066Aclock * 0.995.5Alpha 21164/21164Aclock * 0.995.5Intel Pentium Proclock * 0.995.5Cyrix 5x86/6x86 clock * 1.005.6Intel Pentium II/IIIclock * 1.005.6AMD K7/Athlonclock * 1.005.6Intel Celeronclock * 1.005.6Intel Itaniumclock * 1.005.6R4600clock * 1.005.6Hitachi SH-4clock * 1.005.6Intel Itanium 2clock * 1.498.3Alpha 21264clock * 1.9911.1VIA Centaurclock * 1.9911.1AMD K5/K6/K6-2/K6-IIIclock * 2.0011.1AMD Duron/Athlon XPclock * 2.0011.1AMD Sempronclock * 2.0011.1UltraSparc IIclock * 2.0011.1Intel Pentium MMXclock * 2.0011.1Intel Pentium 4clock * 2.0011.1Intel Pentium Mclock * 2.0011.1Intel Core Duoclock * 2.0011.1Intel Core 2 Duoclock * 2.0011.1Intel Atom N455clock * 2.0011.1Centaur C6-2clock * 2.0011.1PowerPC 604/604e/750clock * 2.0011.1Intel Pentium III Coppermineclock * 2.0011.1Intel Pentium III Xeonclock * 2.0011.1Motorola 68060clock * 2.0111.2Intel Xeon MP (32-bit) (hyper-threading)clock * 3.9722.1IBM S390not enough data (yet)ARMnot enough data (yet)

 BogoMIPS 怎么计算的? 
在当前内核(2.6.x),BogoMIPS实现在内核源文件/usr/src/linux/init/calibrate.c。它计算了Linux内核定时参数loops_per_jiffy (see  ) 值。源码解释如下：
<nowiki>
 /*
   * A simple loop like
   *  while ( jiffies < start_jiffies+1)
   *    start = read_current_timer();
   * will not do. As we don't really know whether jiffy switch
   * happened first or timer_value was read first. And some asynchronous
   * event can happen between these two events introducing errors in lpj.
   *
   * So, we do
   * 1. pre_start <- When we are sure that jiffy switch hasn't happened
   * 2. check jiffy switch
   * 3. start <- timer value before or after jiffy switch
   * 4. post_start <- When we are sure that jiffy switch has happened
   *
   * Note, we don't know anything about order of 2 and 3.
   * Now, by looking at post_start and pre_start difference, we can
   * check whether any asynchronous event happened or not
   */
</nowiki>

loops_per_jiffy 用于实现 udelay（微秒级延时）和 ndelay（纳秒级延时）函数。某些驱动程序需要这些函数来等待硬件操作完成。这里采用了忙等待（busy waiting）方法，所以在执行 ndelay 或 udelay 函数期间，内核实际上处于阻塞状态。对于i386结构，delay_loop 的实现在 /usr/src/linux/arch/i386/lib/delay.c 中，如下所示：
/* simple loop based delay: */
static void delay_loop(unsigned long loops)
{
  int d0;

  __asm__ __volatile__(
    "\tjmp 1f\n"
    ".align 16\n"
    "1:\tjmp 2f\n"
    ".align 16\n"
    "2:\tdecl %0\n\tjns 2b"
    :"=&a" (d0)
    :"0" (loops));
}

用C语言重写的代码如下：
static void delay_loop(long loops)
{
  long d0 = loops;
  do {
    --d0;
  } while (d0 >= 0);
}

关于BogoMips更丰富更全的信息和数百篇相关文章可参见 BogoMips mini-Howto.

参考

 外部链接 
 BogoMips Mini-Howto, V38

Category:Linux內核
Category:计算机性能测试