Hatena::ブログ(Diary)

miura1729の日記 このページをアンテナに追加 RSSフィード

2008-11-23

配列の高速化を実装しました

21:17 |  配列の高速化を実装しましたを含むブックマーク  配列の高速化を実装しましたのブックマークコメント

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 なんか寝ぼけてる.そっちにもオーバヘッドがかかってそうですね,と書きたかった.

miura1729miura1729 2008/11/24 07:11 そのオーバーヘッドも削りたかったです。本当はRARRAYの参照も削りたい(RARRAY_PTRをどっかにキャッシュするとかして)のですが、まだやっていないです。

トラックバック - http://d.hatena.ne.jp/miura1729/20081123/1227442635