class OML4R::Benchmark

Monitor the CPU consumption of a block and report it to OML

Public Class Methods

bm(label, opts = {}, &block) click to toggle source
# File lib/oml4r/benchmark.rb, line 23
def self.bm(label, opts = {}, &block)
  inst = self.new(label, opts)
  inst.measure(&block) if block
  inst
end
new(name, opts) click to toggle source
# File lib/oml4r/benchmark.rb, line 149
def initialize(name, opts)
  @name = name
  @running = false
  @paused = false

  @monitor_interval = opts[:periodic] || -1
  @step_cnt = 0
  @step_cnt1 = 0

  @lock = Monitor.new
  @first_report = true
end

Public Instance Methods

measure(&block) click to toggle source

Measure execution of 'block'. Benchmarking is assumed to be finished when block finished. Don't attempt to call again

# File lib/oml4r/benchmark.rb, line 33
def measure(&block)
  raise "Missing block" unless block
  start
  block.arity == 0 ? block.call() : block.call(self)
  _stop
end
pause() click to toggle source
# File lib/oml4r/benchmark.rb, line 70
def pause()
  t, r = Process.times, Time.now
  @lock.synchronize do
   return unless @running
    return if @paused
    @paused = true

    @paused_t = t
    @paused_r = r.to_f
  end
end
report(label = nil) click to toggle source

Push out an intermediate report. Does nothing if already finished.

NOTE: Not thread safe

# File lib/oml4r/benchmark.rb, line 117
def report(label = nil)
  return unless @running
  _report(label)
end
resume() click to toggle source
# File lib/oml4r/benchmark.rb, line 82
def resume()
  @lock.synchronize do
    unless @running
      # hasn't been kicked off yet
      start
      return
    end

    return unless @paused
    t, r = Process.times, Time.now
    off_u = t.utime - @paused_t.utime
    off_s = t.stime - @paused_t.stime
    off_t = r.to_f - @paused_r
    @t0 = Struct::Tms.new(@t0.utime + off_u, @t0.stime + off_s)
    @r0 = @r0 + off_t
    if @t1
      @t1 = Struct::Tms.new(@t1.utime + off_u, @t1.stime + off_s)
      @r1 = @r1 + off_t
    end
    @paused = false
  end
end
start() click to toggle source
# File lib/oml4r/benchmark.rb, line 51
def start()
  @lock.synchronize do
    raise "Don't call this directly" if @running
    @running = true
  end

  if @monitor_interval > 0
    Thread.new do
      while @running
        sleep @monitor_interval
        _report()
      end
    end
  end
  @t0, r0 = Process.times, Time.now
  @t1 = @t0
  @r1 = @r0 = r0.to_f
end
step(cnt = 1) click to toggle source

Report a step in the processing. Used to calculate a progress rate

NOTE: Not thread safe

# File lib/oml4r/benchmark.rb, line 127
def step(cnt = 1)
  @step_cnt += cnt
end
stop() click to toggle source
# File lib/oml4r/benchmark.rb, line 105
def stop
  @lock.synchronize do
    return unless @running
  end
  _stop
end
task(&block) click to toggle source

Execute block and add execution time to overall measurements. Can be called multiple time. Need to finally call '#stop' to report overall stats.

# File lib/oml4r/benchmark.rb, line 44
def task(&block)
  raise "Missing block" unless block
  resume
  block.arity == 0 ? block.call() : block.call(self)
  pause
end

Private Instance Methods

_inject(label, is_absolute, is_final, t1, r1, t0, r0, step_cnt) click to toggle source
# File lib/oml4r/benchmark.rb, line 192
def _inject(label, is_absolute, is_final, t1, r1, t0, r0, step_cnt)
  d_u = t1.utime - t0.utime
  d_s = t1.stime - t0.stime
  d_t = r1 - r0
  #puts "INJECT0 #{d_u} #{d_s} #{d_t}"
  return if (d_t <= 0 || (d_s + d_u) <= 0)
  BenchmarkMP.inject @name, label, is_absolute, is_final, step_cnt, step_cnt / d_t, step_cnt / (d_u + d_s), d_t, d_u, d_s
end
_report(label = '-', is_final = false) click to toggle source
# File lib/oml4r/benchmark.rb, line 169
def _report(label = '-', is_final = false)
  t, r = Process.times, Time.now
  @lock.synchronize do
    if @paused
      # report ONCE while paused
      return if @paused_r == @last_paused_r
      @last_paused_r = @paused_r
      t = @paused_t
      r = @paused_r
    end
    r = r.to_f
    _inject(label, true, is_final, t, r, @t0, @r0, @step_cnt)
    unless (is_final && @first_report)
      # don't report incremental on final if this would be the first incr
      _inject(label, false, is_final, t, r, @t1, @r1, @step_cnt - @step_cnt1)
    end
    @t1 = t
    @r1 = r
    @step_cnt1 = @step_cnt
    @first_report = false
  end
end
_stop() click to toggle source
# File lib/oml4r/benchmark.rb, line 162
def _stop
  _report('done', true)
  @lock.synchronize do
    @running = false
  end
end