fd0の陰謀に巻き込まれる形で、第1回LLVM(Low Level Virtual Machine)勉強会に参加してきた。ちなみに前提知識はゼロ。仕方ないので当日色々調べながら話を聞こうとしたら、会場がEMOBILE圏外でお手上げ状態だった。そんな状態から、取り敢えず印象に残った事をメモしておいた中から、感想&まとめとして今回ブログに書こうと思う。
難しい事は、fd0のエントリを見て欲しい。それでも物足りない人は、自分で調べてくれ。
会場はネットの孤島
会場は恵比寿ガーデンプレイスの地下1階、マクドナルドの隣にある、日本SGIのホール。何か、結構直前まで暗くて、ホール前には参加者っぽい人々がゾンビのようにたむろってた。あの微妙な空気がたまらん。
会場はSGI内って事で、入り口からホールの間にある部屋の中にセグウェイとか発見。乗りたかった。
で、会場内は無線LANが使えたらしいが、俺のノートPCにはそんな装置付いてないので、EMOBILEを接続しようとしたら圏外。残念すぎる。また、無線LANもリソースが少なかったらしく、殆どの人はネットに繋げない状態だったようだ。
ちなみに、斉藤ゾンビと言うのは実在する人物で、お化け屋敷のプロデュースなどをやっていると見られる。
この間99+に出ていた。
LLVM Intro
今回の勉強会では、syoyoさんと言う人が殆ど喋っていた。
1回目なので、発表者が集まらなかった(と言うか、あまり募集してなかった?)と言うのが理由だが、この人はCG業界の人らしい。俺は全然知らなかったんだが、このLLVM、CG業界の方に有用な使い道があるとの事。ちょっと意外だ。何か、レンダリング速度が凄い上がるらしい。確かにデモを見る限り、凄い画質のリアルタイムレンダラみたいなのがあった。
メモから探索したキーフレーズ
- プログラムを「ゆりかごから墓場まで」最適化し続ける
- しかし、実際には最適化を行う「実行時プロファイル」が実装されていないので、即座に墓場行き状態らしい。残念すぎる。JARO呼ぶか。
- コンパイラを作るためのインフラである
- Python用に、PyPyなる性的なコンパイラがあるらしい。
- LeopardのOpenGLスタックやiPhone用コンパイラに使われている
- Appleでコーダを募集しているらしい
で、デモを見たんだが、何かややこしかった。
llvm-gcc
とか言う、「こいつに任せれば勝手に全部やってくれる」みたいなコマンドがあるが、実はこいつ単体だとgcc
と同じ動きをするとか。何のためにあるコマンドなんだ?
実際には何かコマンドを大量発行する必要があるようだ。頑張って書き写してたけど、資料も公開されてるし馬鹿らしくなって止めた。
で、LLVMと言うのは、まずC言語などで書かれたソースファイルを一旦LLVM用の中間言語(LLVM bitcode)に変換し、その後お好きな環境で動くバイナリに変換すると言う2段構えの仕組みで、それぞれ「Frontend」「Backend」と言う。で、Frontend→中間言語、中間言語→Backendの変換を行う機構が、LLVM IRっていうのかな?今思い出してもよく分からない。勉強会当時は分かっていた気がする。
沢山コマンドを発行しているのは、上記2回の変換処理や、最適化のためのようだ。
利点として、以下が挙げられる。
- 実務的
- llvm-gccはFull Cサポートだから、gccツールチェインとの親和性が高いからとの事。意味は分からないが。
- 実践的
- 利用実績が結構多いらしい。あまり見えてこないが。
- 活発
- 沢山の開発者が参加している。X86ばかりだが。
- ライセンスが緩い
- は製品をクローズドにしても問題ない、Illinois OSL
また、向かない分野として以下が挙げられていた。が、「向かない」の意味が2つで違うように見えて、ちょっと混乱する。
- 動的言語に向かない
- GCがないかららしい。自分で実装すればよいようだが…。
- 組み込みに向かない
- ライブラリが凄いデカイかららしい。ただ、デカイのは中間言語をインタプリタ的に走らす部分なので、中間言語をバイナリ化してしまえば関係無いようだ。
最後にデメリット。
- 仕様や実装がよく変わる
- 開発者の気まぐれ?で、バージョンごとに使える命令が変わったりする。下位互換無し
- assertが邪魔っけ
- そこかしこにassertが埋め込まれており、ちょっとでもオリジナルな事をやろうとするとすぐアサートエラーになるらしい。しかも、失敗時の情報が少なく、そこからの進展が見込めない
中間言語
多分発表の切れ目ではないが、俺のメモの中で切れ目っぽくなってたので一旦区切る。
LLVMアセンブリだとか、LLVM bitcodeと呼ばれる中間言語の話。
まず、メモから探したキーフレーズ。
llvm-gcc
- パーサ+LLVM IR+LLVM Backendで、普通のコンパイラとして動くらしい。LLVMの特性を生かして使う時は、LLVM IRの後のbitcodeに対して、LLVMアセンブリを行う必要があると書いてある。何の事だ?
lli
- デフォルトの動作ではJITコンパイルを行う、LLVM用インタプリタ。オプションを使うと逐次実行するが、処理は遅いとの事。
llc
- LLVM中間言語のコードをアセンブリコードにするツール?よくわからない。
- C言語⇒LLVM中間言語⇒LLVMによる最適化⇒C言語に書き戻し
- この作業によって、良い感じに最適化が自動化できるかも?
Adding LLVM JIT facility to your program
- オンラインコンパイラを実装する時に参考になる話
- サンプルの「HowToUseJIT」が参考になる
- The Pure Programming Languageがいいサンプルになる
Partial evaluation with LLVM
実行時に引数の値を見て、コンパイルの最適化度合いを変更するという話。JITコンパイル用かな?
この技術が3DCGのレンダリングに活かせるようだ。例えば光源の位置を変えるときは、他の要素をPartial evaluationによって定数化してしまうと、かなりのクオリティのCGがリアルタイムに動くんだとか言うデモ動画を見せてもらった。
例えば、
- double mypow(double x,int n) {
- int i;
- double r = 1;
- for(i=0;i < n;i++) {// >
- r *= x;
- }
- return r;
- }
みたいなコードで、nが常に3だと分かっている場合、for文で回す必要が無くて、以下のようなコードになる。
- double mypow(double x,int n) {
- double r;
- r = x * x * x;
- return r;
- }
これがPartial evaluationと言うものらしい。
が、このパターンが何千個にもなる(nが1,2,…9999とか)とメモリ的にきついので、数を工夫しなくてはならないとの事。
LLVM first steps
HowToUseJITというサンプルっぽいものを自力で実装したと言う話。
- define float @func()
- {
- retu float 1.3
- }
と言うコード(LLVMのbitcode)をllvm-asmでコンパイル出来ないらしい。理由はIEEE754では1.3が正確に表現できないから。
An LLVM benchmark
LLVMの何かしらのベンチマークテスト結果。何をテストして何の速度比較をしたのかはよく分からなかったが、gccが最速と言う結果を出して終了。まぁ、LLVMはそういう速さを求めてない気がする。あと、発表者は寝巻きにサンダルで来ていた(ように見えたが違うらしい)。
[Program][Bin] LLVM勉強会 11:43参照。
オレ言語の LLVM フロントエンドコンパイラの作り方
Python用のpy2llvmと言うのを作ったと言う話。SIMD命令を簡単に扱いたいと言うのが動機らしい。
Python compilerモジュールやllvm-pyなど、色々便利なものが揃っている模様。ただ、Pythonは型が無い(コード時に定義しなくてよい)ので、型推論を実装したらしい。
出来たものは、「py2llvm – Google Code」にあるそうだ。
バイナリだけが出力じゃない
最も基本的なイントロダクションがあり、非常に分かりやすかった。この人の発表の前半部分を最初に見ておきたかった。
LLVMのBackendと言うのは、通常バイナリを出力するためのものだが、実はJavaScriptのコードみたいな、バイナリ以外のものも(凄い頑張れば)出せるという話。
キーフレーズ:
- 内部を書き換えない最適化パスを、ImmutablePassと言う
- Backend処理も実はパスの一種
- Backendを自作するのは、勉強になると言うくらいのメリットしかない。
- .NET用のBackendを元に、ABC用のBackendを作った人がAdobe社内にいるらしい。ただし趣味なので、外には出てこないだろうとの事。
全体の感想
さすがLLVM勉強会と言うだけあって、ロウレイヤーな考え方を持った人が多かった。しきりに「LLVM bitcodeは人間が書くものではない」などと言う当たり前の事を繰り返したりする辺りにそれを強く感じた。
後、飲み会の予約を37人で取ってたのに実際は30人しか居なくて涙目みたいになってた。鍋はかなり食えた。飯が幾つか余っていた。