2005-10-06

近況

健康診断の結果は冷徹に告げていた. あなたの体重(の増分)は指数的に増加しています. その趨勢に私は電子回路の集積度を連想し, この新たな微分傾向に名前をつけることはしまい, なぜなら来年で終わるのだから, そう固く誓った. おかわり, 大盛り, 揚げ物禁止. そして一口残すこと. 誓いを書き加えた診断結果のシートはデスクに貼りつけられた. しかしついさっき完食したうどんの皿を思い出し, 私はある予感に身震いする.

The Free Lunch Is Over

私の体重と同じく, CPU の集積度, あるいはクロック数の増加は近々頭打ちになるだろう. 現実を見よ. C++ の雄である Herb Sutter は警告する. どうせ CPU が速くなる, そんな言訳はもう通用しなくなるのだと. 恐しい話だ. 今こそ並列プログラミングの能力が必要とされていると Sutter は煽る. ここでは thread safety ではなく thread efficiency が問題になる. (thread safety は前提条件.) プログラムが thread efficient であるとは, 要するにスレッドが増えたときにちゃんと速くなるということ. これが思ったより難しいらしい. 多くのウェブ・アプリケーションやそのフレームワークはそれなりに thread efficient であるように見えるが, それは問題領域が比較的単純だからうまくいっているだけとも言える. 同時にやってくる複数クライアントからの要求は(少なくともデータベースの手前では)独立しており, 並列化しやすい. 排他制御の難しそうな部分はほとんど OS の下に隠れている.

Sutter が気にしているのは, 現在シングルスレッドか, あるいは非対称な定数個のスレッドで動いているアプリケーションのようだ. 多くのデスクトップ用アプリケーションはそのように作られている. 今まで並列処理でなかったコードを並列化する方法は自明でない. たとえばメモリ・アロケータ. 多くのメモリ・アロケータは thread efficient でない. 並列処理を意識したメモリアロケータの実装 HOARD はそう主張している. (Google も似たようなものを作っている "The fastest malloc we've seen" といっているが HOARD を see したのかは不明.) 言われてみればメモリ空間は複数スレッドで共有されているから, ベタに作ると遅くなりそうだ. 一方で言われてみなければ気付かないことでもある.

このような "マルチスレッドにすると遅くなるけれどそれに気付いていない領域" は細々としたろころで結構残っている気がする. データベースやコンパイラのように, もともと時間がかかって並列化の要求があった分野はよく研究されているだろうけれど, 対話的なアプリケーションは開拓の余地がありそうだ. たとえば thread effiecient なウィンドウ・システム, テキストエディタ, 表計算, レンダリング・エンジン, ウェブブラウザ, メーラ, シェル, 手書き認識 ... なんでもいい. 自分の得意な問題領域を thread effiecient にする技術は, プログラマにとっての新しい挑戦になるだろう. (いやだなあ...)

速度をアフォードする言語

とはいえ願わくば C++ で並列プログラミングはしたくない. マルチスレッドを言語レベルで支援する Java を使ってすら並列プログラミングは難しい. それを C++ でやろうとは身の毛がよだつ. なにしろ言語仕様はまるっきりスレッドに言及していないのだから. (Sutter によれば.) C++ プログラマをこんなにも怖気づかせる記事が C++ の雑誌に書かれていたことに驚く. あるいはこれを読んで奮いたたないような C++ プログラマはやっていけないのかもしれない.

記事の中で, Applications are likely to become increasingly CPU-bound. Efficiency and performance optimization will get more, not less, important. という部分は C++ プログラマを勇気づける. 性能面の要求から C や C++ を選ぶことは多いだろう. C++ に関係する書籍を読む限り C++ プログラマは高速化に貪欲だし, それなりに自信をもっているように見える. (本のタイトルからして Effective だの Efficient だのとついている.) Java の利用者は JIT コンパイラの高性能化を謳い, それが時に C++ のコンパイラを上回るのは事実だろうけれども, C++ で書かれたソフトウェアはもう少し根深い理由で高速なのだと私は思う. うさんくさい言い方をすれば, C++ は速度を "アフォードする".

C++ は値を返すのにも RVO などいちいち気をつかう余地を残しているし, キャストをなくすだけで十分なはずの generics(template) はどういうわけか inline 化を促すし, だいたい inline 関数の方が書くのが簡単だし, new で確保すればいいオブジェクトも stack に積みたがる(その方が寿命管理が楽だ)し, 各種チェック機能は条件付コンパイルで排除したがるし, 値渡しを嫌がって参照渡しなんて文法があるし, 過剰にコンパイル時の前計算を要求するし, などなど. このように執拗で, 時に醜いまでの高速化を強調する言語仕様と暮らすプログラマは, 嫌でも CPU sensitive になってしまう. Java プログラマが abstraction sensitive になるのも同じ理由だろう. 言語がアフォードするのだ. (例は省略.) ほかの言語たちもそれぞれ違う何かをアフォードするだろう.

だから C++ と Java で同じプログラムを書くと Java の方が速いという議論は虚しく響く. C++ プログラマと Java プログラマはおそらく同じコードを書かない. C++ プログラマの方が, より速度を意識したコードを書く傾向があるはずだ. なにしろわざわざ面倒な C++ を使っているんだから.

そんな風に考えると, これからはもう CPU は速くならない, だからコードに速度が要求されるんだ! などと C++ 雑誌が煽る理由もわかってくる. 言語がアフォードするのだ. これからはビジネスがどんどん変化する, だからその変化に対応できる柔軟さやロジックの抽象化が要求されるんだ! Java 雑誌がそう煽るように.

定時退社とダイエットをアフォードする言語はないかなあ...