SPVMのJIT実装をこれから始める
Perlの数値計算を速くするために、研究・開発しているSPVMプロジェクト。現在は、バイトコード実装なのですが、もうすこしで、JIT実装を始められそう。実行時にコンパイルして、すべてを機械語にする。
目標はC言語のパフォーマンス
目標はC言語で「-O3」で最適化したときのパフォーマンスだ。このパフォーマンスを出すことができれば目標達成。
実装を始めると必ず困難にぶつかるけれど、現在の予想として、十分可能だと感じている。
その理由は、
- SPVMは型と関数がコンパイル時に完全に決定される
- それゆえ、完全なC言語のソースコードにトランスパイルできる
- そのソースコードを「-O3」でコンパイルできる
完全にC言語にトランスパイルできるとしたら、インライン展開、定数伝播、レジスタ割り当てや、ループ最適化などの非常に難しい最適化をgccに任せることができる。
Perlには「ExtUtils::CBuilder」というモジュールがあって、LinuxでもMacでWindowsでも、実行できる共有ライブラリ(.dllや.so)を生成することができる。
ExtUtils::CBuilderを使うと、Perl自体をコンパイルしたコンパイラを使って(通常はgcc)、実行時コンパイルすることができる。
つまり、SPVMを、C言語にトランスパイルして、ExtUtils::CBuilderで「-O3」でコンパイルして共有ライブラリにする。
SPVMの実装の難しいところ
動的な世界と静的な世界の架け橋
Perlは型も関数も完全に動的な言語だ。一方SPVMは、型も関数も完全に静的な言語だ。完全に動的な世界から、完全に静的な世界へ、橋をかけないといけない。
この変換処理は、意外に大変そうだ。
書くコードの量が多い
書いているコードの量は、今までのプロジェクトの中で、おそらく一番多い。C言語なので、少しの修正に対して、書かないといけない量が多い。少しのことをやろうとしても、結構なコーディング量になる。
そして、セグメンテーションフォールトの嵐。普通のセグメンテーションフォールトは、デバッガで追えるけれど、本当に辛いのは、意図せずにメモリ破壊が起こったとき。デバッガで負えないので、セグメンテーションフォールトが起こる最小限のテストケースを試行錯誤しながら作る。
メモリ破壊は、本当に涙目ものですよね。
未知の世界
こうしたらできるんじゃないかなぁと仮説を立てながらコーディングをしていくのだけれど、現実には、そう簡単にはうまくいかない。あちらが立つと、こちらが立たず、こちらをやろうとすると、こちらができず。本当に実装が、可能なのかどうかもわからない。
試行錯誤でチャレンジする。
SPVMができると、数値計算がPerlでできる。統計処理、ビッグデータ、人工知能、信号処理、画像処理の実装をPerlで書けるようになる。たとえば、ネット上で何かのアルゴリズムがJavaで書かれていたら、それを、Perl + SPVMで書いて、パフォーマンスの目標も達成できる。
GPGPUプログラミングのバインディングがpythonで書かれていたら、本当に簡単にSPVMで書けるようなる。インフラストラクチャが出来上がると、Perlでは対応できなかった、ものすごくたくさんの分野のプログラミングが書けるようになるのでがんばる。