2008-11-23
配列の高速化を実装しました
|yarv2llvmはデータマイニングやグラフィックスなど速度が必要なプログラムで、Hot spotになっているところを高速化するという感じで使うことを考えています。このような場合、行列計算など配列の操作が多いのではないかなと思います。
これまで配列の参照(opt_aref)はrb_ary_entryを呼び出すことで行っていたのですが、この場合は関数呼び出しとインデックスの範囲チェックの分オーバヘッドを生じます。そこで、インデックスの範囲チェックを行うか否かを指定するコンパイルオプションを作りました。オプションで、範囲チェックをしないとすると、rb_ary_entryを呼び出す代わりに配列の構造体を直接アクセスするコードが生成されます。
ただし、この機能には問題があってほとんど実用になりません。というのは、Rubyの最新版では配列は要素数が4以上と未満でデータ構造が異なるからです。アクセス時に場合分けすればいいのですが、そうすると速度低下してしまいます(それより面倒ってのが大きい)。配列の操作で高速化したいのは要素数が多い配列でしょうから場合分けするより、配列の要素は4以上だと決めてしまった方がいいと判断しました。そういうことで、範囲チェックしないオプションを指定すると、テスト(test/test_compile.rb)が失敗して、Segmentation Faultが出ます。
そういうリスク一杯の機能ですが、eを約10000桁求めてみると(http://d.hatena.ne.jp/miura1729/20081116/1226837201)こんな感じでちょっと効果があります。
範囲チェックあり(これまで) real 0m2.676s user 0m1.904s sys 0m0.654s 範囲チェック無し real 0m2.085s user 0m1.622s sys 0m0.498s Ruby 1.9.0で実行した場合 time ruby19 -r sample/e-aux.rb -e 'compute_e' real 0m13.151s user 0m13.061s sys 0m0.124s
ささだ
2008/11/24 06:16
rb_ary_entry() は,ary[-1] とかもチェックしているので,そっちもチェック必要でしょうね.
ささだ
2008/11/24 06:19
なんか寝ぼけてる.そっちにもオーバヘッドがかかってそうですね,と書きたかった.
miura1729
2008/11/24 07:11
そのオーバーヘッドも削りたかったです。本当はRARRAYの参照も削りたい(RARRAY_PTRをどっかにキャッシュするとかして)のですが、まだやっていないです。
- 27 http://www.rubyist.net/~kazu/samidare/
- 4 http://www.google.co.jp/search?hl=ja&safe=off&client=firefox-a&rls=com.ubuntu:en-US:unofficial&hs=tlt&q=py2llvm&start=10&sa=N
- 2 http://a.hatena.ne.jp/fujita-y/detail
- 2 http://reader.livedoor.com/reader/
- 2 http://www.google.co.jp/search?hl=ja&client=firefox-a&rls=org.mozilla:ja:official&hs=BKb&q=Ruby 高速化&btnG=検索&lr=lang_ja
- 2 http://www.google.co.jp/search?hl=ja&lr=lang_ja&q=ypsilon+scheme&revid=475036140&sa=X&oi=revisions_inline&resnum=1&ct=broad-revision&cd=2
- 2 http://www.google.co.jp/search?hl=ja&q=ypsilon+scheme&lr=
- 2 http://www.google.co.jp/search?q=llvmruby&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a
- 2 http://www.google.co.jp/search?q=llvmruby&lr=lang_ja&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:ja:official&client=firefox-a
- 1 http://a.hatena.ne.jp/asip/