未来のいつか/hyoshiokの日記

hyoshiokの日々思うことをあれやこれや

未踏の感想

2002年度のわたしの成果報告書の「おわりに」。未踏に応募した動機を記している。長いけど、そのまま全文掲載する。何がしかのヒントになればと思う。http://hardmeter.sourceforge.jp/mitoufinal.pdf *1

おわりに

未踏ソフトウェア創造事業に採択され約半年間開発してきたわけだが、最後に未踏プログラマとしての感想を述べたい。

わたしは、90 年代中頃、米国に本社のあるデータベースベンダで開発者をしていた。そこには社内で開発された命令数を計測するプロファイリングツールがあった。それを利用して自分が担当するモジュールの命令数を計測してみたところ、簡単にそのモジュールのホットスポットを発見できた。米国に赴任したばかりで、実のところ、そのデータベースエンジンの実装についてはまだ知らないことばかりだったので、担当モジュールの動的特性を知る上でプロファイリングツールが非常に役に立つのだという強い印象を持った。そのツールを利用して、いくつかの改良をほどこしたところ、実行命令数を20〜30 %削減したことを記憶している。

しかし、そのツールは命令数を計測するだけで、どの命令がどのくらい実行コストがかかるとかの情報は提供してくれなかった。しかも、ユーザーモードしか計測できないので、システムコールのコストやカーネルモードでの実行コストに関する情報は一切提供しなかった。さらに投機的実行での分岐予測ミスなどプロセッサのミクロな挙動についての情報も提供しなかった。

普通のデータベースエンジン開発者にとっては機能開発とバグフィックスがトッププライオリティで、日々の細々したパフォーマンスチューニングは性能上の問題が発覚しないかぎり後回しにされるのが常であった。

ある時性能評価を専門とするエンジニアがSun のSolaris のエンジニアと共同で、パフォーマンスに関するハックを開発者全員にメールした。それは、例外処理マクロの定義に関するものだった。データベースエンジンでなんらかのシグナルを発行する場合(例外であったり、単なるメッセージであったり、非同期の処理を起動する場合であったり、様々な場所で使われる) のマクロの処理フローのif 文の条件部を従来はthen 側に例外処理、else 側に通常処理という風になっていたのを逆にするだけで、実行時間が10 数%向上したというものであった。

それは正にハックであった。一つのファイルの一つのマクロの定義を変更するだけで、実行時間を向上させたのである。

SPARC の場合、分岐予測はthen 側に行くので、より多く通過する処理をthen 側においておくと分岐予測ミスのペナルティを払わなくてすむ。例外処理の場合、例外が発生することはまれであるので、その処理をelse 側に記述しておくのが、性能向上に役にたつのである。

普通のデータベース開発者は分岐予測ミスのペナルティを測定するツールを持っていなかったが、Sun のエンジニアは当然なんらかのツールを持っていたのだろう。

ちなみに分岐予測ミスのペナルティの削減は最近ではコンパイラが面倒を見てくれるので、一昔前のようにif...then...else で悩まなくてもよい。profile guided optimization として知られる技法は、実行プロファイリングから分岐する確率が高い方へ積極的に分岐するようなコードを生成する。

そんなわけでプロセッサレベルのミクロなチューニングに興味を持ったのだが当時は実際に簡単に利用できるツールがなかったため仕事で利用するまでにはいたらなかった。

一方で、90 年代の中頃からcommercial work load の分析というのがさかんにおこなわれてくるようになった。従来のSPEC benchmark などではメモリ利用量が小さかったり、カーネルの利用がほとんどなかったり、あるいは単純なメモリアクセスのため、CPI (Cycle Per Instruction) が極限まで下り(1 以下)、プロセッサの評価の指標として疑問視されはじめてきた。その結果、より大規模なアプリケーションであるOLTP(TPC-C) などcommercial work load の分析、研究がさかんになってきた。それらは、メモリ利用量がSPECに代表されるベンチマークより多く、カーネルモードでの実行も多かった。そして実行時間のストールがメモリアクセスによるというのが、それらの研究であきらかになってきた。

わたし自身は90 年代後半に日本に戻ってきて開発の現場から足をあらいサポート部隊に異動になったのでマイクロアーキテクチャレベルでのチューニングという問題について実装にかかわるということは残念ながらなかった。

2000 年にミラクル・リナックス株式会社の立ち上げに参加したこともあり長らくそのような事を考える事もなかった。

横浜Linux Users Group (通称YLUG) では、不定期でカーネル読書会というのを有志で開催しているのだが、その会合でIA-32TSC (Time Stamp Counter) の利用方法が話題になった。ユーザーモードで簡単にハードウェアクロック数を計測できるというのを知って、それをきっかけに、いろいろ調べてみると、IA-32 では簡単に各種パフォーマンスイベントを収集できるらしいというのがわかってきた。キャッシュミスやTLB ミスなどメモリトラフィックに関係するイベントもちょっとしたドライバと設定だけで計測できるらしいというのを教えてもらったりした。

簡単なテストプログラムを作ってキャッシュミスのコスト(クロック数) を計測して遊んでみた。

丁度、そのころ未踏ソフトウェア創造事業が平成14 年度もプロジェクトを公募するということを知り、IA-32 のパフォーマンスモニタリングファシリティを利用したメモリプロファイリングツールを開発するというアイデアで応募したところ幸いにも採択され、今回のプロジェクトにいたっている。

仕事がらLinux Kernel のチューニングに興味があって、カーネルレベルのチューニングをするにはカーネルレベルでのプロファイリングをなんとかしないといけないだろうと思っていた。カーネルハッカーはプロファイリングツールなんかなくとも鼻歌まじりに勘とヒラメキですごいコードを書いて性能向上をするのだろうけど、フツーのプログラマはプロファイリングをとってボトルネックを発見し、ちまちまコードを改良するしかない。

そもそもメモリプロファイリングツールを作りたいという動機は米国にいたころに逆のぼって、あのハックに出あったからだと思う。ちょっとした工夫で性能を劇的に向上させる。

そのためにプロファイリングツールを作りたかった。

そしてYLUGカーネル読書会IA-32 の機能を知り、おぼろげながら実装のイメージもつかめたのが今回のアイデアである。

いくつかの偶然がかさなりあってプロジェクトが発足した。

しかしプロジェクトを開始するまでまじめにIntel のSoftware Developer’s Manual の第3 巻([5]) を読んだことはなかったし、プロジェクトが実質的に開始した8 月の中頃にIntel から無料でそのマニュアルが送付されてきて、(なんというタイミングだろう) それをすみからすみまで読むまでは、今回の実装のメインのアイデアである精密なイベントサンプリング(PEBS – Precise Event Based Sampling) というのを知らなかった。

90 年代の研究のサーベイをすればするほど、メモリプロファイリングはネタとしては非常にスジがいいということを確信し、さらにPEBS によって従来では不可能だった精密なメモリプロファイリングができるということを確認したことによってその確信はますます強固になっていった。

従来のプロファイラとは一線を画したのではないかと自負している。

他のマイクロプロセッサで今回のようなツールを開発できるかは不明である。PEBS はPentium 4/Intel Xeon に依存した機能であるからだ。しかし最近のマイクロプロセッサは各種パフォマンスモニタリングカウンタを持つので(精密でない) イベントベースのサンプリングツールを実装することは可能であろう。

メモリレイテンシとプロセッサの処理スピードのギャップは当面拡大していくことが予想できるので本ツールのようなメモリプロファイリングツールの必要性は益々増えていくと思う。

最後に実装についてふれておく。

インテルIA-32 のパフォーマンスモニタリングファシリティを利用できるようにしたものとして、表2がある。perfctr [8] はP6 およびPentium 4/Intel Xeon に対応している。しかしPEBS には未対応である。abyss [9] はPentium 4/Intel Xeon には対応しておりPEBS にも対応しているが、P6 は対応していない。またLinux Kernel 2.4 系のみに対応している。rabbit [10] は、P6 だけに対応しており、PEBS やPentium 4には対応していない。また最近メンテナンスされていないようである。PAPI [11] はマルチプラットフォームなパフォーマンスライブラリである。パフォーマンスモニタリングファシリティの機能については、perfctr[8] を利用しているが、Pentium 4 およびPEBS には対応していない。以上のツールは全てオープンソースで、インターネット上で入手できる。PEBS に対応しているのは、現状ではabyss [9] だけである。

われわれはperfctr [8] をベースに、PEBS 対応、Linux Kernel 2.4/2.5 対応のドライバおよび設定を容易にするGUI ツールなどを開発した。

開発当初PEBS に対応していたのはabyss [9] だけであったので予備実験はabyss を利用した。しかしabyss はSMP やHyperThreding に対応していないため開発のベースにすることはなかった。

hardmeter ドライバの実装等は久保氏(kubo@jiubao.org) にご協力いただいた。YLUG のメンバである。またプロジェクトマネージャの喜連川東京大学教授には本プロジェクトにおいて様々なご指導をいただいた。ここに記して感謝したい。

追記:

以上は、成果報告書2003年月20日からの転載である。記述については、その当時のままであることをお断りしておく。

*1:各種ドキュメント、成果等は次にあるので、参考にしてほしい。 http://hardmeter.sourceforge.jp/ipa.html