From: Ciro Santilli Date: Tue, 17 Mar 2020 16:51:14 +0000 (+0000) Subject: stats: add --stats-root option to dump only under some SimObjects X-Git-Tag: v20.1.0.0~517 X-Git-Url: https://git.libre-soc.org/?p=gem5.git;a=commitdiff_plain;h=187ffa5be88af1ab9b025c0f73578246d7d4b016 stats: add --stats-root option to dump only under some SimObjects This commit makes it possible to make invocations such as: gem5.opt se.py --stats-root 'system.cpu[:].dtb' --stats-root 'system.membus' When --stats-root is given, only stats that are under any of the root SimObjects get dumped. E.g. the above invocation would dump stats such as: system.cpu0.dtb.walker.pwrStateResidencyTicks::UNDEFINED system.cpu1.dtb.walker.pwrStateResidencyTicks::UNDEFINED system.membus.pwrStateResidencyTicks::UNDEFINED system.membus.trans_dist::ReadReq but not for example `system.clk_domain.clock`. If the --stats-root is given, only new stats as defined at: Idc8ff448b9f70a796427b4a5231e7371485130b4 get dumped, and old ones are ignored. The commits following that one have done some initial conversion work, but many stats are still in the old format. Change-Id: Iadaef26edf9a678b39f774515600884fbaeec497 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/28628 Reviewed-by: Andreas Sandberg Maintainer: Andreas Sandberg Tested-by: kokoro --- diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 3542de9fe..adf33b295 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,3 +1,7 @@ +# Version 20.1.0.0 + +* m5.stats.dump() root argument renamed to roots to reflect the fact that it now takes a list of SimObjects + # Version 20.0.0.2 **[HOTFIX]** A patch was applied to fix the RubyPrefetcher with MESI_Three_Level. Prior to this fix a segfault occurred. diff --git a/configs/common/Options.py b/configs/common/Options.py index 3eff04bf9..0409fb809 100644 --- a/configs/common/Options.py +++ b/configs/common/Options.py @@ -361,6 +361,14 @@ def addCommonOptions(parser): parser.add_option("--arm-iset", default="arm", type="choice", choices=["arm", "thumb", "aarch64"], help="ARM instruction set.") + parser.add_option("--stats-root", action="append", default=[], help= + "If given, dump only stats of objects under the given SimObject. " + "SimObjects are identified with Python notation as in: " + "system.cpu[0].dtb. All elements of an array can be selected at " + "once with: system.cpu[:].dtb. If given multiple times, dump stats " + "that are present under any of the roots. If not given, dump all " + "stats. " + ) def addSEOptions(parser): diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py index e53c755c6..e7fb8789e 100644 --- a/configs/common/Simulation.py +++ b/configs/common/Simulation.py @@ -451,6 +451,12 @@ def run(options, root, testsys, cpu_class): if options.repeat_switch and options.take_checkpoints: fatal("Can't specify both --repeat-switch and --take-checkpoints") + # Setup global stat filtering. + stat_root_simobjs = [] + for stat_root_str in options.stats_root: + stat_root_simobjs.extend(root.get_simobj(stat_root_str)) + m5.stats.global_dump_roots = stat_root_simobjs + np = options.num_cpus switch_cpus = None diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index a045fb7b0..7f12856be 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2019 ARM Limited +# Copyright (c) 2017-2020 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -1071,6 +1071,9 @@ class SimObjectCliWrapper(object): out.extend(sim_object[i] for i in _range) return SimObjectCliWrapper(out) + def __iter__(self): + return iter(self._sim_objects) + # The SimObject class is the root of the special hierarchy. Most of # the code in this class deals with the configuration hierarchy itself # (parent/child node relationships). @@ -1695,6 +1698,18 @@ class SimObject(object): for param in params: exec(param, d) + def get_simobj(self, simobj_path): + """ + Get all sim objects that match a given string. + + The format is the same as that supported by SimObjectCliWrapper. + + :param simobj_path: Current state to be in. + :type simobj_path: str + """ + d = self._apply_config_get_dict() + return eval(simobj_path, d) + # Function to provide to C++ so it can look up instances based on paths def resolveSimObject(name): obj = instanceDict[name] diff --git a/src/python/m5/stats/__init__.py b/src/python/m5/stats/__init__.py index 1e37a14b3..6c4a42cb8 100644 --- a/src/python/m5/stats/__init__.py +++ b/src/python/m5/stats/__init__.py @@ -326,35 +326,45 @@ def prepare(): # New stats _visit_stats(lambda g, s: s.prepare()) -def _dump_to_visitor(visitor, root=None): - # Legacy stats - if root is None: - for stat in stats_list: - stat.visit(visitor) - +def _dump_to_visitor(visitor, roots=None): # New stats def dump_group(group): for stat in group.getStats(): stat.visit(visitor) - for n, g in group.getStatGroups().items(): visitor.beginGroup(n) dump_group(g) visitor.endGroup() - if root is not None: - for p in root.path_list(): - visitor.beginGroup(p) - dump_group(root if root is not None else Root.getInstance()) - if root is not None: - for p in reversed(root.path_list()): - visitor.endGroup() + if roots: + # New stats from selected subroots. + for root in roots: + for p in root.path_list(): + visitor.beginGroup(p) + dump_group(root) + for p in reversed(root.path_list()): + visitor.endGroup() + else: + # Legacy stats + for stat in stats_list: + stat.visit(visitor) + + # New stats starting from root. + dump_group(Root.getInstance()) lastDump = 0 +# List[SimObject]. +global_dump_roots = [] -def dump(root=None): +def dump(roots=None): '''Dump all statistics data to the registered outputs''' + all_roots = [] + if roots is not None: + all_roots.extend(roots) + global global_dump_roots + all_roots.extend(global_dump_roots) + now = m5.curTick() global lastDump assert lastDump <= now @@ -363,7 +373,7 @@ def dump(root=None): # Don't allow multiple global stat dumps in the same tick. It's # still possible to dump a multiple sub-trees. - if not new_dump and root is None: + if not new_dump and not all_roots: return # Only prepare stats the first time we dump them in the same tick. @@ -378,7 +388,7 @@ def dump(root=None): for output in outputList: if output.valid(): output.begin() - _dump_to_visitor(output, root=root) + _dump_to_visitor(output, roots=all_roots) output.end() def reset():