Annotation of hatari/tools/debugger/hatari_spinloop.py, revision 1.1

1.1     ! root        1: #!/usr/bin/env python
        !             2: #
        !             3: # Copyright (C) 2013 by Eero Tamminen
        !             4: #
        !             5: # This program is free software; you can redistribute it and/or modify
        !             6: # it under the terms of the GNU General Public License as published by
        !             7: # the Free Software Foundation; either version 2 of the License, or
        !             8: # (at your option) any later version.
        !             9: #
        !            10: # This program is distributed in the hope that it will be useful,
        !            11: # but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            12: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            13: # GNU General Public License for more details.
        !            14: """
        !            15: Usage: hatari_spinloop.py <filename>
        !            16: 
        !            17: Script for post-processing Hatari profiler looping information
        !            18: produced by "profile loops <filename>" command, after profiling is
        !            19: enabled with either "profile on" and/or "dspprofile on".
        !            20: 
        !            21: That Hatari command saves spinloop data for any CPU and DSP code inner
        !            22: loop that spins for more than once.
        !            23: 
        !            24: This script gives counts on how many times loops were executed, how
        !            25: many times they spinned at minimum and maximum, at which VBL those
        !            26: happened, and what was the standard deviation of that.
        !            27: 
        !            28: Note: in some cases Hatari can list different sized spinloops for the
        !            29: same loop (start) address. This can be because code changed, or outer
        !            30: loop was sometimes repeated several times in succession without
        !            31: repeating the inner loop.
        !            32: """
        !            33: 
        !            34: import os, sys, math
        !            35: 
        !            36: 
        !            37: class LoopItem:
        !            38:     def __init__(self, addr, size):
        !            39:         self.addr = addr
        !            40:         self.size = size
        !            41:         self.loops = []
        !            42: 
        !            43:     def add(self, count, vbl):
        !            44:         self.loops.append((count, vbl))
        !            45: 
        !            46:     def stats(self):
        !            47:         "return max + its VBL, min + its VBL, count of separate loops, stddev for them, loop addr & size"
        !            48:         self.loops.sort()
        !            49:         count = len(self.loops)
        !            50:         if count > 1:
        !            51:             mean = sum([x for x,y in self.loops]) / float(count)
        !            52:             mean2 = sum([(x-mean)**2 for x,y in self.loops]) / float(count-1)
        !            53:         else:
        !            54:             mean2 = 0.0
        !            55:         return (self.loops[-1][0], self.loops[-1][1],
        !            56:                 self.loops[0][0], self.loops[0][1],
        !            57:                 count, math.sqrt(mean2), self.addr, self.size)
        !            58: 
        !            59: 
        !            60: def output(processors, write):
        !            61:     for name, data in processors.items():
        !            62:         write("\n%s loop statistics\n" % name)
        !            63:         sorted = []
        !            64:         for item in data.values():
        !            65:             sorted.append(item.stats())
        !            66:         sorted.sort()
        !            67:         sorted.reverse()
        !            68:         write("   max:\tat VBL:\t   min:\tat VBL:\ttimes:\tstddev:\taddr:\tsize:\n")
        !            69:         for item in sorted:
        !            70:             write("%7d\t%7d\t" % (item[0], item[1]))
        !            71:             write("%7d\t%7d\t" % (item[2], item[3]))
        !            72:             write("%7d\t%7.1f\t" % (item[4], item[5]))
        !            73:             write(" %06x\t%6d\n" % (item[6], item[7]))
        !            74: 
        !            75: 
        !            76: def parse(fname):
        !            77:     "parse looping information from given file object"
        !            78:     processors = {}
        !            79:     for line in open(fname).readlines():
        !            80:         if line[0] == '#':
        !            81:             continue
        !            82:         name, vbl, addr, size, count = line.split()
        !            83:         if name not in processors:
        !            84:             processors[name] = {}
        !            85:         items = processors[name]
        !            86:         addr = int(addr, 16)
        !            87:         size = int(size)
        !            88:         ident = (addr, size)
        !            89:         if ident not in items:
        !            90:             items[ident] = LoopItem(addr, size)
        !            91:         items[ident].add(int(count), int(vbl))
        !            92:     return processors
        !            93: 
        !            94: 
        !            95: if __name__ == "__main__":
        !            96:     if len(sys.argv) != 2 or not os.path.exists(sys.argv[1]):
        !            97:         print __doc__
        !            98:         sys.exit(1)
        !            99:     data = parse(sys.argv[1])
        !           100:     output(data, sys.stdout.write)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.