Profilerの実験

とりあえず、こんな感じでProfilerを作ってみました。掛かったクロック数を行毎に表示します。ソースコード兼出力結果です。yarv2llvmで実行するのはただのfibなので、そこだけクロック数が表示されています。後は、Profilerそのもののプログラムです。
以下のプログラムを実行(sample/profile_sketch.rb)すると、下のような結果が表示されます。

	1:  require 'yarv2llvm'
	2:  module YARV2LLVM
	3:    PROFILER_STATICS = []
	4:    PROFILER_STATICS[0] = 0
	5:  end
	6:  
	7:  YARV2LLVM::compile(<<-EOS, {})
	8:  module YARV2LLVM
	9:    def trace_func(event, no)
	10:      if event == 1 then # Line
	11:        if $fst == 1 then
	12:          get_interval_cycle
	13:          $fst = 0
	14:        end
	15:        next_curtime = get_interval_cycle
	16:        PROFILER_STATICS[no] += $curtime
	17:        
	18:        $curtime = next_curtime
	19:        # Profile process dont count
	20:        get_interval_cycle
	21:      end
	22:    end
	23:  end
	24:  
	25:  def fib(n)
238808	26:    if n < 2 then
125921	27:      1
	28:    else
	29:      fib(n - 1) + 
116821	30:      fib(n - 2)
	31:    end
	32:  end
	33:  
	34:  EOS
	35:  
	36:  YARV2LLVM::TRACE_INFO.each_with_index do |n, i|
	37:    YARV2LLVM::PROFILER_STATICS[i] = 0
	38:  end
	39:  $fst = 1
	40:  $curtime = 0
	41:  p fib(10)
	42:  
	43:  src_content = {}
	44:  YARV2LLVM::TRACE_INFO.each do |n|
	45:    fn, ln = n[1][3].split(/:/)
	46:    src_content[fn] = File.readlines(fn)
	47:  end
	48:  
	49:  res = {}
	50:  YARV2LLVM::TRACE_INFO.each_with_index do |n, i|
	51:    fn, ln = n[1][3].split(/:/)
	52:    res[n[1][3]] = YARV2LLVM::PROFILER_STATICS[i]
	53:  end
	54:  
	55:  src_content.each do |fn, cont|
	56:    cont.each_with_index do |srcln, ln|
	57:      re = res[fn + ":" + (ln + 1).to_s].to_i
	58:      if re != 0 then
	59:        print "#{re}\t#{ln + 1}:  #{srcln}"
	60:      else
	61:        print "\t#{ln + 1}:  #{srcln}"
	62:      end
	63:    end
	64:  end
	65:  

追記

eを1000桁もとめるプログラムでもやってみました。そろそろオーバフローしそうなのでdoubleで計算しようとしましたが、うまく行きません。
結果は大体、腑に落ちるけど一部腑に落ちないところもあります。Profilerが悪いのかコンパイルされたコードがそうなっているのかチェックしてみます。

追記2
やっぱり間違えていた。結果を直しておきます。また、doubleで計算できるようになりました。単純な原因で変数の初期値がintだったからでした。

               1:  #!/bin/env ruby 
               2:  # Compute E without bignum
               3:  #
               4:  KETA = 257
               5:  
               6:  # dst / n -> dst
               7:  def div(n, dst)
    524010     8:    i = 0
    494416     9:    r = 0
    470995    10:    while i < KETA do
 152744427    11:      d = dst[i] + r * 10000
 127691791    12:      r = d % n
 190099591    13:      dst[i] = d / n
 141472614    14:      i = i + 1
              15:    end
              16:  end
              17:  
              18:  def add(src, dst)
    510488    19:    i = KETA - 1
    465654    20:    c = 0
    510625    21:    while i >= 0 do
 163258346    22:      t = src[i] + dst[i] + c
 123676676    23:      c = t / 10000
 199402363    24:      dst[i] = t % 10000
 132127975    25:      i = i - 1
              26:    end
              27:  end
              28:  
              29:  def compute_e
      1008    30:    i = 0
      1155    31:    f = 1
      2573    32:    a = []
      1533    33:    b = []
      1291    34:    while i < KETA do
    442317    35:      a[i] = 0
    435808    36:      b[i] = 0
    263384    37:      i = i + 1
              38:    end
      1617    39:    b[0] = 1
      1617    40:    a[0] = 0
      1029    41:    n0 = 1 
      1092    42:    while f == 1 do
    510661    43:      f = 0
    470073    44:      i = 0
    487312    45:      while i < KETA do
 149543558    46:        if b[i] != 0 then
  64932626    47:          f = 1
              48:        end
 121857093    49:        i = i + 1
              50:      end
 161120547    51:      add(b, a)
  67951021    52:      div(n0, b)
    473062    53:      n0 = n0 + 1
              54:    end
              55:    a
              56:  end