2009-02-10
AOベンチ高速化計画(その2)
|細かいパラメータをいじって、
time ruby19 yarv2llvm.rb --no-type-message sample/ao-render.rb > ao.ppm real 2m48.370s user 2m46.888s sys 0m0.732s
という記録を出しました。前は200秒だったので、15%くらい速くなっています。いじったパラメータはメソッド内にいくつそのインスタンス変数があればキャッシュするかというものです。
こんな背景から、インスタンス変数のアドレス(lvalue)をキャッシュしています。
- yarv2llvmではRubyのAPIを使って直接読み書きすることもできます。でも、そうするとアクセスのたびにハッシュテーブルを引くことになります。
- そこでインスタンス変数のlvalueをスタック上にキャッシュし、インスタンス変数のアクセスをキャッシュしたlvalueに対して行うようにします。lvalueは本物の変数のアドレスですから、ちゃんと別のメソッドから参照しても正しい値が得られます。
しかし、メソッド内に1つしか変数が無ければ(そしてそれがループ内でなければ)、キャッシュしても無意味ですし、スタック上にlvaueを書き出すだけ無駄になります。そういうことで、メソッド上にいくつインスタンス変数があるか数えています、そしてある閾値を越えるまでキャッシュしないようにしています。しかし、サンタ問題を動かすのには常にlvalueがキャッシュされている必要があるので、常にキャッシュするように設定されていました。それを最適な値(2)としたら、速くなりました。
一方、うまいアイデアが浮かんだので試してみました。Inline cacheのようなものをインスタンス変数にも適用するというもので、個々のインスタンス変数のアクセスについて(または、キャッシュを設定している場所について)、2つのグローバル変数(「Rubyの」ではなく、「LLVMの」)を用意します。1つは前回アクセスした時のself、もう1つは前回アクセスしたときのlvalueを入れておきます。Rubyはselfのインスタンス変数しか直接アクセスできないので、selfが前回と同じなら同じlvalueになっているはずです。そこで、もう1つのグローバル変数からlvalueを得ます。もし、selfが前回と違えば通常のようにハッシュを検索します。
これでかなり速くなるぞって思ったら遅くなりました。
real 3m45.814s user 3m43.842s sys 0m0.826s
コメントを書く
トラックバック - http://d.hatena.ne.jp/miura1729/20090210/1234272466
リンク元
- 5 http://www.rubyist.net/~kazu/samidare/
- 2 http://d.hatena.ne.jp/keyword/アドレス
- 1 http://a.hatena.ne.jp/cranebird/mobile
- 1 http://a.hatena.ne.jp/fujita-y/
- 1 http://k.hatena.ne.jp/keywordblog/イテレータ
- 1 http://k.hatena.ne.jp/keywordblog/CodeGen
- 1 http://lucille.atso-net.jp/aobench/
- 1 http://search.minakoe.jp/rsss/rsss.asp?qry=domain:hatena&multi=1
- 1 http://www.google.co.jp/search?hl=ja&rlz=1B3GGGL_jaDE227DE230&q=多相インラインキャッシュ&btnG=検索&lr=
- 1 http://www.google.com/search?hl=ja&q=Ypsilon+scheme&btnG=検索&lr=lang_ja