Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
[go: Go Back, main page]

Floating point Mistery
11/29 浮動小数点ミステリー





accident

 米国ではシーグラフというコンピュータ・グラフィックスの展示会があり、年に一度、CGに関する最新の研究成果や、企業のアピールなどを目指して開催されていることで世界的に有名である。

 そのシーグラフを真似て、我が国でもNicographというコンピュータ・グラフィックスの展示会が毎年開催されている。私は昨日、そのNicographに行く道中で、京葉線に揺られながら先日作ったばかりのプログラムのベンチマークをとっていた。

 ちょうど新浦安をすぎたあたりだったろうか。私は比較的すいている座席でノートパソコンの画面を食い入るように見つめた。その結果は明らかに、私の期待していたものとは違っていたのだ。

 


 前回、私はPentiumプロセッサは整数演算よりも浮動小数点演算のほうがより得意であることを論じ、整数化ブレゼンハムアルゴリズムの他に、浮動小数点数を用いたより簡易なものを例として示した。

 さらには私は浮動小数点数を用いた演算の方がより高速であるという知識(3D野郎会チャットでのMitamex氏の書き込みなど)から、後者のアルゴリズムの方が、より効率的であろうことも示唆した。

 

 ところが現実に目の前にある液晶ディスプレイが示しているのは、整数化ブレゼンハムが18秒で終了するのと同じ処理を、浮動小数点をもちいたアルゴリズムでは56秒もかかってしまうという、ため息の出るような結果だ。

 いったいこの結果はなんだろう。
 私は急いでソースコードを隅々まで確認したが、特に目立つ違いは見当たらない。

 


suspect

 ぜんたいこれはどういうことなのか。

 私は愛用の黒いノートパソコンをレジュームさせ、VisualC++コンパイラの最適化オプションを一通り調査した。

 Pentium専用の最適化モード。速度優先・・・これでおかしな結果がでるわけはないのだが・・・。

 コンパイラが正常に作動しているということは、私の知識が誤っているのである。

 そう仮定すると、いくつかの予想が浮かんできた。

 ひとつは、浮動小数点演算そのものは高速でも、整数化がボルトネックとなっているケース。これは大いに有り得る(後で読んだが、掲示板でも恋塚氏が同様の指摘をしている)。

 しかし、それではたとえ浮動小数点計算がいくら早くても無意味ではないか。どんなデータでも最終的には整数化して外部出力することになる。その変換に手間取っていては、この(CPU自体の)高速化のメリットは少ない。

 仕方がないので、私はコンパイラのリスティングファイルオプションを選択し、アセンブリ言語レベルで検証してみることにした。

 すると、そこに僅かだが重大な違いがあることに気づいた。

 それは浮動小数点から整数への変換部分だ。

 そういう意味では予想通りだが、致命的なことに、そこではプロセッサ本来がもっている変換命令ではなく、_ftolという(おそらくはfloat to longの略だ)内部関数を呼び出していたのだ。

 原因はこれかもしれない。そう思い、ひとまずその部分を自力でfist命令に書き換えて再度コンパイルしてみた。しかし残念ながら状況は一向に改善されない。

 私はソースコードをにらみつけた。

 はた目に見ても、浮動小数点バージョンの方が、整数化ブレゼンハムよりもぐっと単純である。

 浮動小数点が高速であるならば、こちらの方がググッと差をつけてもよさそうなものだ。

 なぜなら、浮動小数点演算バージョンには分岐はない。だから分岐予測の読み違いというのも起り得ない。パイプラインはフル可動のハズである・・・・パイプライン?浮動小数点は厳密にはコプロセッサだからパイプラインは別系統の可能性は高い。しかし何本あるかわからない。そう、そういえば私はPentiumプロセッサ・シリーズの内部構造について、実はなにひとつ知らないではないか!

 言い訳ではないが、私が以前、パソコンのアセンブリ言語でプログラムをしていたのは486プロセッサが最新鋭と言われていた頃だった。その後は86系とは全く命令形態の異なる、某コンシューマ機のMIPS社製RISC(縮小命令セット)チップのアセンブリ言語ばかり使っていたため、再びパソコンに戻った頃には、アセンブリ言語を再学習する必要性を感じていなかったのだ。

 私は自分の興味のないことを勉強することを苦痛と思い、それを大変嫌う。従ってアセンブリ言語のように習得が面倒でなおかつすぐに実用になるわけでもないものを最初から選択したりはしない。常にそれは「最期の手段」として降りかかってくるのである。

 しかし今や私は仮にも80人余の生徒にプログラムのなんたるかを説く身、いつまでも不勉強のままではいられない。そしてこの謎に直面したいまこそが「最期の手段」を行使する絶好の機会だと考え、京葉線から東京駅で乗り換え、秋葉原に向かった。

To be continued.