米国はiPhoneの話題でもちきり。販売店の前には、その筋の方々が列をなしているそうな。そういえば最近、行列することがなくなりました。新宿高島屋の前に並んだとき、道行く人々に「なんだあいつらは」といった目で見られたことも遠い昔のようです。
さて、今回は「LLVM」について。LLVMは仮想マシンの一種で、今秋登場するLeopardへの採用が決まっている。これまでなんとなく紹介しそびれていたが、5月下旬に最新版「LLVM 2.0」がリリースされたこともあり、これを機会に仕組みや特徴について説明してみたい。
What's LLVM ?
LLVMは、Low Level Virtual Machineという正式名称が示すとおり、仮想マシンとしての機能を持つ実装系。対応するプラットフォームは、現在のところOS XとWindows(Mingw)、Linuxの3種。あまりメディアでは取り上げられていないが、今秋登場のLeopardではOpenGLスタックにLLVMの技術を使うことが明らかにされており、要注目の存在なのだ。
その特徴は、"動的かつ静的"に最適化を行うこと。実行時のプロファイリングによりデータを収集しつつコンパイルするというJavaVMライクな(動的な)最適化に加え、実行終了後に収集したデータをもとに(静的な)最適化を実行するという二段構えの処理により、利用される環境に応じた最適なバイナリができあがる。最適化はユーザの使い方にも影響を受けるため、あたかも道具が手になじむように、使い込むうちにアプリケーションが最適化されるというわけだ。
LLVMで動作するアプリケーションは、LLVM対応のGCCフロントエンド(llvm-gcc)を利用して作成する。CやC++で記述されたソースコードをコンパイルという流れに変わりはないが、その結果生成されるのは通常のバイナリファイルではなく、仮想マシンであるLLVM用の中間コード。JavaのClassファイルや.NETのアプリケーションを想像すると、わかりやすいかもしれない。
LLVMをTigerにインストールする
LLVMの動作環境は、仮想マシン部分とGCCフロントエンド部分の2つのパートに分かれている。仮想マシン部分はソースコードを手動でコンパイル、フロントエンド部分はMac OS X用にコンパイル済のバイナリパッケージを利用すると便利だろう。
具体的なインストールの手順は、以下のとおり。なお、バイナリパッケージはIntel / PowerPCで分かれているため、PowerPCユーザはファイル名の「x86」部分を「ppc」に置き換え読み進めていただきたい。
GCCフロントエンド部分のインストール
$ cd ~
$ curl -O http://llvm.org/releases/2.0/llvm-gcc4-2.0-x86-darwin8.tar.gz
$ cd /usr/local
$ sudo tar zxf ~/llvm-gcc4-2.0-x86-darwin8.tar.gz
仮想マシン部分をインストールする前には、コマンドサーチパスの設定も必要。bashの場合、以下のとおりコマンドを実行すればOK。継続的に利用する場合は、~/.profileなどのスタートアップファイルに書き加えてほしい。
export PATH=/usr/local/llvm-gcc4-2.0-x86-darwin8/bin:$PATH
仮想マシン部分のインストール
$ curl -O http://llvm.org/releases/2.0/llvm-2.0.tar.gz
$ tar xzf llvm-2.0.tar.gz
$ cd llvm-2.0
$ ./configure
$ make
$ sudo make install
一見同じだがちょっと違うバイナリの完成
さて、これでLLVMが使えるようになったわけだが、そろそろ紙幅が尽きそう……というわけで、こちらからDhrystoneベンチマークを入手し、ZIP書庫を解凍すると生成される懐かしのSHAR書庫を展開(sh dhrys.[1-4]と実行すればOK)、dhrystone.cの387行目を「50000」から「10000000」に変更 & 上書き保存したあと、以下のとおり2通りの方法でコンパイルしてほしい。
チェックすべき点は2つ、生成されたバイナリのファイルサイズと、処理速度の違い。otoolコマンドで調べればわかるが、バイナリがリンクするライブラリも異なる。というわけで、この続きはまた来週。
$ /usr/bin/gcc-4.0 dhrystone.c -o normal
$ llvm-gcc dhrystone.c -o llbin
$ ls -l normal llbin
-rwxr-xr-x 1 shinobu shinobu 18040 6 28 21:35 llbin
-rwxr-xr-x 1 shinobu shinobu 13924 6 28 21:36 normal
$ ./normal
Dhrystone(1.1) time for 10000000 passes = 3
This machine benchmarks at 3311258 dhrystones/second
09:45 PM shinobu@MacBook ~/work
$ ./llbin
Dhrystone(1.1) time for 10000000 passes = 3
This machine benchmarks at 3144654 dhrystones/second