nbodyが動きました

yarv2llvmでnbodyが動きました。まだ、attr_accessorとかサポートしていないので、プログラムに手を加えています。
sample/bm_so_nbody.rbがソースです。(http://github.com/miura1729/yarv2llvm/tree/master/sample/bm_so_nbody.rb)

実行速度を測ってみました。N=200_000です。

Ruby 1.9

-0.169075164
-0.169083713

real	0m16.674s
user	0m16.577s
sys	0m0.108s

yarv2llvm

-0.169075163828524
-0.169083712569648

real	0m6.576s
user	0m5.982s
sys	0m0.592s

これは、コンパイル時間込みの場合です。その場合で2倍強、コンパイル時間が約2秒くらいなのでコンパイル時間を入れないと3倍強という感じです。fibだと30倍以上だったので、ずいぶんな速度低下です。インスタンス変数のアクセスとかRubyのランタイムを呼びまくっているのでこんなものかなーと思います。インスタンス変数のアクセスをキャッシュするとかすると速度が上がるんじゃないかなと思っています。
それよりも、nbodyみたいな比較的複雑なプログラムでも型矛盾を起さずにコンパイルできてしまうことにびっくりです。

追記(2008/12/13)
インスタンス変数のlvalueをスタック上にキャッシュするようにしてみました。

-0.169075163828524
195827.292170961

real	0m5.342s
user	0m4.872s
sys	0m0.483s

ちょっと速くなるが答えが違う。おそらくバグが取れてもこれより速くなることは無いと思うのでこの方法でも5倍くらいまでしか行かないようです。この場合も型変換のオーバヘッドが残るのですが、これを何とかする方法が思いつきません。
ドキュメントに
「Real Programmers Don't Use Instance Variables」
とか
「Instance Variables Considered Harmful
とか書いておいたほうが効果があるのかもしれません。

追記2(2008/12/14)
バグが取れました。ポインタのデリファレンスの回数を間違えていました。

-0.169075163828524
-0.169083712569648

real	0m5.333s
user	0m4.716s
sys	0m0.638s

スピードアップの方法を考えました。インスタンス変数を型推論で決定したネイティブな表現で格納する配列を用意し、そのポインタをstruct RObjectのstruct st_table *iv_index_tblに格納するって方法です。llvmから復帰するときは、RCLASS_IV_INDEX_TBL(rb_obj_class(obj))で戻しておきます。