stattrace.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. """
  2. stattrace.py
  3. Write a trace of deltas for an arbitrary statistic.
  4. First argument is the name of the statistic (<component-name>[.<subcomponent>].<stat-name>)
  5. Second argument is either a filename, or none to write to standard output
  6. Third argument is the interval size in nanoseconds (default is 10000)
  7. """
  8. import sys, os, sim
  9. class StatTrace:
  10. def setup(self, args):
  11. args = dict(enumerate((args or '').split(':')))
  12. stat = args[0]
  13. filename = args.get(1, None)
  14. interval_ns = long(args.get(2, 10000))
  15. if '.' not in stat:
  16. print 'Stat name needs to be of the format <component>.<statname>, now %s' % stat
  17. return
  18. self.stat_name = stat
  19. stat_component, stat_name = stat.rsplit('.', 1)
  20. valid = False
  21. for core in range(sim.config.ncores):
  22. try:
  23. sim.stats.get(stat_component, core, stat_name)
  24. except ValueError:
  25. continue
  26. else:
  27. valid = True
  28. break
  29. if not valid:
  30. print 'Stat %s[*].%s not found' % (stat_component, stat_name)
  31. return
  32. if filename:
  33. self.fd = file(os.path.join(sim.config.output_dir, filename), 'w')
  34. self.isTerminal = False
  35. else:
  36. self.fd = sys.stdout
  37. self.isTerminal = True
  38. self.sd = sim.util.StatsDelta()
  39. self.stats = {
  40. 'time': [ self.getStatsGetter('performance_model', core, 'elapsed_time') for core in range(sim.config.ncores) ],
  41. 'ffwd_time': [ self.getStatsGetter('fastforward_performance_model', core, 'fastforwarded_time') for core in range(sim.config.ncores) ],
  42. 'stat': [ self.getStatsGetter(stat_component, core, stat_name) for core in range(sim.config.ncores) ],
  43. }
  44. sim.util.Every(interval_ns * sim.util.Time.NS, self.periodic, statsdelta = self.sd, roi_only = True)
  45. def periodic(self, time, time_delta):
  46. if self.isTerminal:
  47. self.fd.write('[STAT:%s] ' % self.stat_name)
  48. self.fd.write('%u' % (time / 1e6)) # Time in ns
  49. for core in range(sim.config.ncores):
  50. timediff = (self.stats['time'][core].delta - self.stats['ffwd_time'][core].delta) / 1e6 # Time in ns
  51. statdiff = self.stats['stat'][core].delta
  52. value = statdiff / (timediff or 1) # Avoid division by zero
  53. self.fd.write(' %.3f' % value)
  54. self.fd.write('\n')
  55. def getStatsGetter(self, component, core, metric):
  56. # Some components don't exist (i.e. DRAM reads on cores that don't have a DRAM controller),
  57. # return a special object that always returns 0 in these cases
  58. try:
  59. return self.sd.getter(component, core, metric)
  60. except:
  61. class Zero():
  62. def __init__(self): self.delta = 0
  63. def update(self): pass
  64. return Zero()
  65. sim.util.register(StatTrace())