2. BogoMips についてのよくある質問

BogoMips について何人かの方がわたしに詳しい情報を提供してくれました。 ここで彼らに深く感謝したいと思います。

2.1. BogoMips とは

誰が言い出したのかは分かりませんが、Eric S Raymond <esr@thyrsus.com> と Geoff Mackenzie <freon@dialstart.net> から教った、インターネット 上でよく使われる BogoMips の特徴を捉えた定義に次にようなものがあります。 「プロセッサが一秒間に何百万回無益な処理をできるかを計測した数値」

1993年9月9日の Lars Wirzenius <wirzenius@kruuna.Helsinki.FI> からの メールに Alessandro Rubini <rubini@norgana.systemy.it> と Wim van Dorst による補足を加えて、BogoMips をより正確に定義すると、以下の ようになります。

MIPS とは、Millions of Instructions Per Second の略であり、プログラムの 計算速度を測る基準値です。こうした基準値にありがちなことですが、適切に 利用されるというより、むしろ間違った使い方をされる傾向にあります (異なる種類のコンピュータ間で MIPS 値を公正に比較することは非常に 困難です)。

BogoMips は、Linus が発明したものです。カーネル(もしかすると最初はデバイス ドライバ用だったかも?)には、マシンのプロセッサ速度を計測するためのタイミング ループが必要です。 このループは短い間隔を正確に計測できなければならないので、待ち状態 での空ループは雑すぎて使えません。そこで、カーネルは起動時にコンピュータ上で 一種のビジーループを実行し、その速度を測ります。"Bogo" は "bogus (偽、いんちき)" に由来するもので、「偽物」を意味します。それゆえ、BogoMips は、プロセッサ速度に関するある種の尺度にはなりますが、あまりにも「非科学的」な 方法でしか計測していないので、BogoMips と呼ばれているわけです。

起動時に BogoMips 値が表示される理由( 2 つあります)は、a) コンピュータのキャッシュやターボスイッチが働いているかどうか デバッグしたりチェックしたりする際に多少とも役に立つこと、および b) Linus 自身、ネットニュース上で他人が戸惑っているのを 見て面白がる癖があるから、です。

BogoMips は、/usr/src/linux/init/main.c のシンプルな C アルゴリズムで測定されています。そして、その値はカーネル変数 loop_per_sec に保持されて、正確なタイミング の計測を必要とする様々なドライバによって利用されます。実際の delay 関数 udelay() は、アセンブラで記述されているので、 個々のアーキテクチャごとの定義ファイルが /include/asm/delay.h に置かれています。この loops_per_sec 変数と udelay 関数はかなりの数のドライバで利用されて いて、以下のようなコマンドを使うと、それを確認できます。

cd /usr/src/linux  #linux のソースファイルがある場所に移動します。
find . -name '*.[hcS]' -exec fgrep loops_per_sec {} /dev/null \; 
find . -name '*.[hcS]' -exec fgrep udelay {} /dev/null \;

BogoMips の計測ループはアセンブラ言語で記述されているので、Intel CPU 以外の 場合、計測ループは類似してはいますが、同一ではありません。ただ、(Intel 製 もしくは Intel 以外の)様々な CPU において、そのおおまかな速度を表示する方法 として、BogoMips は唯一の汎用的な手段となっています。CPU のクロック スピードという基本的情報すら不明だという場合があるからです。

2.2. CPU の種類に応じた BogoMips 値の目安

以下の表は、Ian Jackson <ijackson@nyx.cs.du.edu> と Przemek Klosowski により作成され、Wim van Dorst が現在の状態に更新・拡張したものです。

非常におおまかではありますが、システム別の BogoMips の計測値はだいたい以下の ようになります。

システム                    BogoMips 値           比較
Intel 8088                  clock * 0.004         0.02 
Intel/AMD 386SX             clock * 0.14          0.8 
Intel/AMD 386DX             clock * 0.18          1 (基準値) 
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
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
Mips R4600                  clock * 1.00          5.6 

Alpha 21264                 clock * 1.99         11.1
AMD K5/K6/K6-2/K6-III       clock * 2.00         11.1
AMD Duron                   clock * 2.00         11.1
UltraSparc II               clock * 2.00         11.1
Pentium MMX                 clock * 2.00         11.1 
PowerPC 604/604e/750        clock * 2.00         11.1
Motorola 68060              clock * 2.01         11.2 

Motorola 68040              (今のところ)データ不足
IBM S390                    (今のところ)データ不足

BogoMips の計測ループは、Intel Pentium や Alpha 21164 といった各種プロセッサ で並列処理した場合、まだ完全にその並列化の利点を生かし切れないので注意して ください。

2.3. 現在の BogoMips 値の確認方法

現在のマシンの BogoMips 値を確認する方法は 3 種類あります。すなわち、

  1. /proc/cpuinfo を見る方法。例えば、'cat /proc/cpuinfo' とします。これが一番おすすめの方法であり、 他はその代替手段です。

  2. syslog の出力を見て、起動時に表示されていたメッセージを確認する方法 (必要に応じて、dmesgsyslogk を 使って、情報を引き出してください)。この方法を使うと正確な情報が得られますが、 ちょっと入力が面倒ではあります。

  3. bogomips プログラムを単独で使う方法。この方法は、お使いのシステムが Linux でない場合しかおすすめできません。理由は以下で説明します。

必ずしも最良の方法とは言えませんが、Cray などの Linux 以外のシステムにも 適用できるのが、この bogomips プログラムを単独で使う方法です。 Jeff Tranter <jeff_tranter@mitel.com> による README ファイル には次のように書かれています。

わざわざシステムの再起動をしなくとも、今日どの程度の BogoMips 値を出して いるのか確認できないだろうかと思ったことはないでしょうか? [...] "bogomips" は、世界的に認知されたベンチマーク値のひとつを使って、 システムのパフォーマンスを表示するスタンドアローンのプログラムです。 これは、起動時に Linux で使用されるものと同じコードを使っていますが、 ユーザプログラムとして実行することができます。[...] BogoMips バージョン 1.3 は現在様々なアーキテクチャに対応しており、ANSI C コンパイラとライブラリ をサポートしているどのようなシステム上でも動くようになっています。

ただ、スタンドアローンプログラムが計測した値は、システム負荷の関係で、 後ほど掲載するリストに登録されている値よりも低めになることに注意してください。 もともと、スタンドアローンプログラムがブートシーケンスの BogoMips 値と 厳密に同じ値を表示するというのは無理なのです。一般ユーザの権限で動くこの プログラムは、システム負荷の影響を直接受けるからです。それゆえ、後ほど 掲載するリストでは、ブートシーケンスの BogoMips 値のみを記載しています。

sunsite.unc.edu:/pub/Linux/system/status/bogo-1.2.tar.gz という ファイルには最新版のバージョン 1.3 (ママ) が含まれていますが、これは もう既にやや内容が古くなっています。とはいえ、システムを選ばないプログラム なので、C コンパイラが使えるほとんどすべてのシステム上でコンパイルして 実行することができます。

2.4. BogoMips 値のゆれ

Linus Torvalds <torvalds@cc.helsinki.fi> は、ユーザが目にする BogoMips 値のゆれについて、ニュースグループ comp.os.linux.development で次のように 説明しています。

BogoMips 計測ループは「量子化」されているので、毎回ほぼ確実 に同じ値を表示します。ただ、違う計測値が表示されたりするのは、(その時の割り込み 信号の違いなどで、)端数部分が繰り上がったり切り捨てられたりすることが あるからです。

マシンの CPU に合わせてカーネルがコンパイルされていない場合、主に最適化が 上手くいかずに、そうした BogoMips 値のゆれが(上記の場合よりも顕著に)生じる ことがあります。この問題は、種々の x86 CPU (Intel 製やそのクローン) 上で のみ目立つ現象です。さいわい、これは簡単に解決できます。CPU に合わせて、 カーネルを再コンパイルすればいいのです。

2.5. BogoMips のアルゴリズムの更新は?

一般の期待に反して、BogoMips アルゴリズムはカーネルのバージョンが上がっても 全く変更されていません。加えて、どこのメーカの CPU に関しても本質的に同じ ものが使われています。

カーネル 2.2.14 で変更されたのは、BogoMips の計測直前での CPU ステートの設定 です。この変更の影響は、Intel および AMD の Pentium 系 CPU すべての BogoMips 値に及んでいて、それによって今まで BogoMips 値は 2*clock ではなかったところ、 約 2*clock となりました。こうしたカーネルバージョンの更新による変更については、 以下のリストにおいて * 印でマークしてあります。

2.6. BogoMips ... failed という表示

これに関する質問は、ネット上でも個人メールでも数多く寄せられました。例えば、 Lily <lbliao@alumni.caltech.edu> や Pierre Frenkiel < frenkiel@cdfap2.in2p3.fr> といった方々からです。1995年3月には、次のような 質問がありました。

Linux を起動すると以下のようなメッセージが表示されます。

  Calibrating delay loop.. ok - 23.96 BogoMips failed

calibration delay loop は、どの部分で、何故失敗しているのでしょうか?

いいえ、これは失敗ではありません。もし失敗したのなら、次にような表示に なるはずです。

  Calibrating delay loop.. failed

失敗と表示されるのは、マシン上にないデバイスのドライバが原因ではないかと 思われます。デバイスドライバは、BogoMips 値の計測の直後に初期化されます。 まず SCSI デバイス、次にネットデバイス等々です。初期化に失敗した場合は、 必ずそれが表示されます。とくに AHA152x ドライバでよく問題が起こります。 ドライバの初期化の失敗(および BogoMips 計測の失敗)以外にも、システム クラッシュ、待ち時間の超過やシステムが完全にロックしてしまうといった現象が ok - xx.xx BogoMips を出力する直前や直後に 起こっていることが考えられます。

Linux 1.2 以降ではエラーメッセージの多くが以前よりも改善されているので、 最新版のカーネルを使ってどのドライバが初期化に失敗しているのか確かめるとよいと 思います。また、現在のカーネルを再コンパイルして、ハードウェアの設定に 本当に必要なドライバだけを組み込むようにする方法もあります。

2.7. (Cyrix, NexGen, AMD といった) クローン CPU ではどうか

Cyrix 486 系 CPU には、キャッシュを有効にするソフトウェア(これは、BogoBoost と呼ばれたりします)が必要です。Cyrix 5x86 と 6x86 CPU では、(BIOS オプション の)分岐予測により BogoMips 値が大幅に改善されているようです。ただ、 パフォーマンス自体はそれほど改善されない場合があるので、Cyrix CPU の調整用に BogoBoost パッチや cx5x86mod, set6x86 といったパッケージが作成されています。 これらは一般のアーカイブならどこでも分かり易い場所にあります。また、Cyrix 6x86 CPU では、CPU の最適化に Pentium を選ぶより 486 を選んでカーネルを コンパイルした方がパフォーマンスが向上する場合があることが報告されています。

Nx586 と記載されている NexGen 386 エンハンスド CPU は、この文書では 386 系 CPU としてリストに掲載しています。これらの CPU が Pentium と同様の 動作をするからといって、そのことは BogoMips の計測とは関係ないからです。

AMD 5x86 についても、AMD 486DX5 と記載しています。これは、486/33 を 4 倍速に したものであり、他の 486 CPU と全く同じ系列に属しています。AMD K5 や K6 は、 Pentium 系 CPU であるので、それぞれ適切なリスト上に BogoMips 値の計測結果を 記載しています。

2.8. なぜ BogoMips 値が重要なのか

Linux の起動中に表示される BogoMips 値に注意を払うべき理由は 2 つしかありま せん。それは以下のようなことです。

  1. クロック数やキャッシュ機能などに応じたそのプロセッサに適切な範囲の値が表示 されているか確認するため。CPU の多くは、次にような箇所の設定が適切になされて いないことがあるからです。

    • メモリキャッシュの設定。(ライトバック(write-back)にすると 5 % ほど BogoMips が下がると言われています。ライトスルー(write-through)にしておけば OK です。)

    • ターボスイッチ。( ON にしておくべきです。)

    • BIOS ソフトウェアを使ったソフトウェアキャッシュのエミュレーション。 (実キャッシュを使うようにしてください。)

    • 上記に類するキャッシュやクロック関連の事柄。また、ときとして、BIOS ソフトウェア 関連の事柄。

  2. 他人のシステムとどちらが早いか比べるため。もちろん、これは全くの間違いであり、 信頼できず、根拠のない、あきらかに無駄な利用方法ですが、どのベンチマークにも 同じ問題はつきまといます。だったら、使っちゃいけないというわけではないだろう、 となる訳です。問題が含まれているとはいえ、みんなベンチマークを使うのを止める ことはなかった、そうじゃありません?

本物のベンチマークをもっと真面目に利用しようと思う場合は、 Andre D. Balsa の Linux Benchmarking HOWTO (日本語訳) をご覧ください。