Hatena::ブログ(Diary)

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

2008-12-15

trace_funcを実装しました

19:18 |  trace_funcを実装しましたを含むブックマーク  trace_funcを実装しましたのブックマークコメント

yarv2llvmをスピードアップするにはprofilerがいるなーと思い、set_trace_func相当のものを作りました。set_trace_funcのそのままだとtrace_funcが設定されているかどうかを静的にチェックするのが面倒そうなので、YARV2LLVM#trace_funcというメソッドがあれば、それをYARVのtrace命令のタイミングで呼ぶようにしました。

    YARV2LLVM::compile(<<-EOS, {})
module YARV2LLVM
  def trace_func(event, line)
    p line
  end
end

def fib(n)
  if n < 2 then
    1
  else
    fib(n - 1) + fib(n - 2)
  end
end
EOS

こんな感じでコンパイルしておいて、fib(3)とすると、

9
10
13
9
10
13
9
10
11
9
9
10
11
9
9
9
10
11
9
9

こんな感じで実行したメソッドの行番号が表示されます。trace_funcはllvmのオプティマイザーでインライン化されますのでオーバヘッドがかなり小さくなりそうです。今のところ、この機能はprofileというブランチを切ってそこに入っています。

ささだささだ 2008/12/15 19:50 すばらしい.

miura1729miura1729 2008/12/15 20:31 ありがとうございます
でも本当にすばらしいのはllvmの最適化ですね。
trace_funcをインライン化するって発想は無かったです。でも、そうすると定数畳み込みと合せて、処理の必要の無いイベントはオーバヘッド無しになります。
llvmの強力な最適化があれば、もう少し過激にリフィレクティブな機能が入れられるかなって考えています。

ささだささだ 2008/12/15 22:21 LLVMの最適化の部分がわからなかったんですが,実行時書き換えで trace_func を有効・無効に変更するってことでしょうか.

miura1729miura1729 2008/12/16 06:25 説明が足りずすみません
イベントの番号はtrace命令の引数から取っているので、定数になるわけです。そう考えると、たとえばtrace_funcが
if (event == CALL)
:
elsif (event == RETURN)
:
end
とかという内容だった場合、trace_funcがインライン化されると、eventが定数なのでif文の条件が静的に決まります。だから、この条件にない例えばLINEとかのイベントはdead code削除で最終的には何もなかったことになるんじゃないかなと思います。

トラックバック - http://d.hatena.ne.jp/miura1729/20081215/1229336295