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.004｜0.02

Intel/AMD 386SX｜clock、0.14｜0.8

Intel/AMD 386DX｜clock、0.18｜1 (definition)

Motorola 68030｜clock、0.25｜1.4

Cyrix/IBM 486｜clock、0.34｜1.8

Intel Pentium｜clock、0.40｜2.2

Intel 486｜clock、0.50｜2.8

AMD 5x86｜clock、0.50｜2.8

MIPS R4000/R4400｜clock、0.50｜2.8

ARM9｜clock、0.50｜2.8

Motorola 8081｜clock、0.65｜3.6

Motorola 68040｜clock、0.67｜3.7

PowerPC 603｜clock、0.67｜3.7

Intel StrongARM｜clock、0.66｜3.7

NexGen Nx586｜clock、0.75｜4.2

PowerPC 601｜clock、0.84｜4.7

Alpha 21064/21064A｜clock、0.99｜5.5

Alpha 21066/21066A｜clock、0.99｜5.5

Alpha 21164/21164A｜clock、0.99｜5.5

Intel Pentium Pro｜clock、0.99｜5.5

Cyrix 5x86/6x86｜clock、1.00｜5.6

Intel Pentium II/III｜clock、1.00｜5.6

AMD K7/Athlon｜clock、1.00｜5.6

Intel Celeron｜clock、1.00｜5.6

Intel Itanium｜clock、1.00｜5.6

R4600｜clock、1.00｜5.6

Hitachi SH-4｜clock、1.00｜5.6

Intel Itanium 2｜clock、1.49｜8.3

Alpha 21264｜clock、1.99｜11.1

VIA Centaur｜clock、1.99｜11.1

AMD K5/K6/K6-2/K6-III｜clock、2.00｜11.1

AMD Duron/Athlon XP｜clock、2.00｜11.1

AMD Sempron｜clock、2.00｜11.1

UltraSparc II｜clock、2.00｜11.1

Intel Pentium MMX｜clock、2.00｜11.1

Intel Pentium 4｜clock、2.00｜11.1

Intel Pentium M｜clock、2.00｜11.1

Intel Core Duo｜clock、2.00｜11.1

Intel Core 2 Duo｜clock、2.00｜11.1

Intel Atom N455｜clock、2.00｜11.1

Centaur C6-2｜clock、2.00｜11.1

PowerPC 604/604e/750｜clock、2.00｜11.1

Intel Pentium III Coppermine｜clock、2.00｜11.1

Intel Pentium III Xeon｜clock、2.00｜11.1

Motorola 68060｜clock、2.01｜11.2

Intel Xeon MP (32-bit) (hyper-threading)｜clock、3.97｜22.1

IBM S390｜not enough data (yet)

ARM｜not 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` 中，如下所示：

```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语言重写的代码如下：

```c
static void delay_loop(long loops)
{
  long d0 = loops;
  do {
    --d0;
  } while (d0 >= 0);
}
```

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

## 外部链接

- BogoMips Mini-Howto, V38