profile.py
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· Python 代码 · 共 504 行 · 第 1/2 页
PY
504 行
# Copyright (c) 2005# The Regents of The University of Michigan# All Rights Reserved## This code is part of the M5 simulator.## Permission is granted to use, copy, create derivative works and# redistribute this software and such derivative works for any purpose,# so long as the copyright notice above, this grant of permission, and# the disclaimer below appear in all copies made; and so long as the# name of The University of Michigan is not used in any advertising or# publicity pertaining to the use or distribution of this software# without specific, written prior authorization.## THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE# UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT# WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR# IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF# THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES,# INCLUDING DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL# DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION# WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER# ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.## Authors: Nathan L. Binkertfrom orderdict import orderdictimport outputclass FileData(dict): def __init__(self, filename): self.filename = filename fd = file(filename) current = [] for line in fd: line = line.strip() if line.startswith('>>>'): current = [] self[line[3:]] = current else: current.append(line) fd.close()class RunData(dict): def __init__(self, filename): self.filename = filename def __getattribute__(self, attr): if attr == 'total': total = 0.0 for value in self.itervalues(): total += value return total if attr == 'filedata': return FileData(self.filename) if attr == 'maxsymlen': return max([ len(sym) for sym in self.iterkeys() ]) return super(RunData, self).__getattribute__(attr) def display(self, output=None, limit=None, maxsymlen=None): if not output: import sys output = sys.stdout elif isinstance(output, str): output = file(output, 'w') total = float(self.total) # swap (string,count) order so we can sort on count symbols = [ (count,name) for name,count in self.iteritems() ] symbols.sort(reverse=True) if limit is not None: symbols = symbols[:limit] if not maxsymlen: maxsymlen = self.maxsymlen symbolf = "%-" + str(maxsymlen + 1) + "s %.2f%%" for number,name in symbols: print >>output, symbolf % (name, 100.0 * (float(number) / total))class PCData(RunData): def __init__(self, filename=None, categorize=None, showidle=True): super(PCData, self).__init__(self, filename) filedata = self.filedata['PC data'] for line in filedata: (symbol, count) = line.split() if symbol == "0x0": continue count = int(count) if categorize is not None: category = categorize(symbol) if category is None: category = 'other' elif category == 'idle' and not showidle: continue self[category] = countclass FuncNode(object): def __new__(cls, filedata=None): if filedata is None: return super(FuncNode, cls).__new__(cls) nodes = {} for line in filedata['function data']: data = line.split(' ') node_id = long(data[0], 16) node = FuncNode() node.symbol = data[1] if node.symbol == '': node.symbol = 'unknown' node.count = long(data[2]) node.children = [ long(child, 16) for child in data[3:] ] nodes[node_id] = node for node in nodes.itervalues(): children = [] for cid in node.children: child = nodes[cid] children.append(child) child.parent = node node.children = tuple(children) if not nodes: print filedata.filename print nodes return nodes[0] def total(self): total = self.count for child in self.children: total += child.total() return total def aggregate(self, dict, categorize, incategory): category = None if categorize: category = categorize(self.symbol) total = self.count for child in self.children: total += child.aggregate(dict, categorize, category or incategory) if category: dict[category] = dict.get(category, 0) + total return 0 elif not incategory: dict[self.symbol] = dict.get(self.symbol, 0) + total return total def dump(self): kids = [ child.symbol for child in self.children] print '%s %d <%s>' % (self.symbol, self.count, ', '.join(kids)) for child in self.children: child.dump() def _dot(self, dot, threshold, categorize, total): from pydot import Dot, Edge, Node self.dot_node = None value = self.total() * 100.0 / total if value < threshold: return if categorize: category = categorize(self.symbol) if category and category != 'other': return label = '%s %.2f%%' % (self.symbol, value) self.dot_node = Node(self, label=label) dot.add_node(self.dot_node) for child in self.children: child._dot(dot, threshold, categorize, total) if child.dot_node is not None: dot.add_edge(Edge(self, child)) def _cleandot(self): for child in self.children: child._cleandot() self.dot_node = None del self.__dict__['dot_node'] def dot(self, dot, threshold=0.1, categorize=None): self._dot(dot, threshold, categorize, self.total()) self._cleandot()class FuncData(RunData): def __init__(self, filename, categorize=None): super(FuncData, self).__init__(filename) tree = self.tree tree.aggregate(self, categorize, incategory=False) self.total = tree.total() def __getattribute__(self, attr): if attr == 'tree': return FuncNode(self.filedata) return super(FuncData, self).__getattribute__(attr) def displayx(self, output=None, maxcount=None): if output is None: import sys output = sys.stdout items = [ (val,key) for key,val in self.iteritems() ] items.sort(reverse=True) for val,key in items: if maxcount is not None: if maxcount == 0: return maxcount -= 1 percent = val * 100.0 / self.total print >>output, '%-30s %8s' % (key, '%3.2f%%' % percent)class Profile(object): # This list controls the order of values in stacked bar data output default_categories = [ 'interrupt', 'driver', 'stack', 'buffer', 'copy', 'syscall', 'user', 'other', 'idle'] def __init__(self, datatype, categorize=None): categories = Profile.default_categories self.datatype = datatype self.categorize = categorize self.data = {} self.categories = categories[:] self.rcategories = categories[:] self.rcategories.reverse() self.cpu = 0 # Read in files def inputdir(self, directory): import os, os.path, re from os.path import expanduser, join as joinpath directory = expanduser(directory) label_ex = re.compile(r'profile\.(.*).dat')
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?