summaryrefslogtreecommitdiff
path: root/src/base/stats/group.cc
diff options
context:
space:
mode:
authorAndreas Sandberg <andreas.sandberg@arm.com>2019-06-26 18:58:24 +0100
committerAndreas Sandberg <andreas.sandberg@arm.com>2019-08-29 09:01:38 +0000
commit6f38428abbe106d63318dd86bfa82a03b6b368ee (patch)
treefb0e758c120bf45d7c017f97396c66cba1bb4792 /src/base/stats/group.cc
parent09281876a77c8ec66560bc91715421491c335c6b (diff)
downloadgem5-6f38428abbe106d63318dd86bfa82a03b6b368ee.tar.xz
stats: Add support for hierarchical stats
This change makes the stat system aware of the hierarchical nature of stats. The aim is to achieve the following goals: * Make the SimObject hierarchy explicit in the stat system (i.e., get rid of name() + ".foo"). This makes stat naming less fragile and makes it possible to implement hierarchical formats like XML/HDF5/JSON in a clean way. * Make it more convenient to split stats into a separate struct/class that can be bound to a SimObject. This makes the namespace cleaner and makes stat accesses a bit more obvious. * Make it possible to build groups of stats in C++ that can be used in subcomponents in a SimObject (similar to what we do for checkpoint sections). This makes it easier to structure large components. * Enable partial stat dumps. Some of our internal users have been asking for this since a full stat dump can be large. * Enable better stat access from Python. This changeset implements solves the first three points by introducing a class (Stats::Group) that owns statistics belonging to the same object. SimObjects inherit from Stats::Group since they typically have statistics. New-style statistics need to be associated with a parent group at instantiation time. Instantiation typically sets the name and the description, other parameters need to be set by overriding Group::regStats() just like with legacy stats. Simple objects with scalar stats can typically avoid implementing regStats() altogether since the stat name and description are both specified in the constructor. For convenience reasons, statistics groups can be merged into other groups. This means that a SimObject can create a stat struct that inherits from Stats::Group and merge it into the parent group (SimObject). This can make the code cleaner since statistics tracking gets grouped into a single object. Stat visitors have a new API to expose the group structure. The Output::beginGroup(name) method is called at the beginning of a group and the Output::endGroup() method is called when all stats, and sub-groups, have been visited. Flat formats (e.g., the text format) typically need to maintain a stack to track the full path to a stat. Legacy, flat, statistics are still supported after applying this change. These stats don't belong to any group and stat visitors will not see a Output::beginGroup(name) call before their corresponding Output::visit() methods are called. Change-Id: I9025d61dfadeabcc8ecf30813ab2060def455648 Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/19368 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Jason Lowe-Power <jason@lowepower.com> Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Diffstat (limited to 'src/base/stats/group.cc')
-rw-r--r--src/base/stats/group.cc129
1 files changed, 129 insertions, 0 deletions
diff --git a/src/base/stats/group.cc b/src/base/stats/group.cc
new file mode 100644
index 000000000..2bfc89d00
--- /dev/null
+++ b/src/base/stats/group.cc
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2019 Arm Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Andreas Sandberg
+ */
+
+#include "base/stats/group.hh"
+
+#include <cassert>
+
+#include "base/stats/info.hh"
+#include "base/trace.hh"
+#include "debug/Stats.hh"
+#include "sim/sim_object.hh"
+
+namespace Stats {
+
+Group::Group(Group *parent, const char *name)
+ : mergedParent(name ? nullptr : parent)
+{
+ if (parent && name) {
+ parent->addStatGroup(name, this);
+ } else if (parent && !name) {
+ parent->mergeStatGroup(this);
+ }
+}
+
+Group::~Group()
+{
+}
+
+void
+Group::regStats()
+{
+ for (auto &g : mergedStatGroups)
+ g->regStats();
+
+ for (auto &g : statGroups) {
+ if (DTRACE(Stats)) {
+ const SimObject *so = dynamic_cast<const SimObject *>(this);
+ DPRINTF(Stats, "%s: regStats in group %s\n",
+ so ? so->name() : "?",
+ g.first);
+ }
+ g.second->regStats();
+ }
+}
+
+void
+Group::resetStats()
+{
+ for (auto &s : stats)
+ s->reset();
+
+ for (auto &g : mergedStatGroups)
+ g->resetStats();
+
+ for (auto &g : statGroups)
+ g.second->resetStats();
+}
+
+void
+Group::addStat(Stats::Info *info)
+{
+ stats.push_back(info);
+ if (mergedParent)
+ mergedParent->addStat(info);
+}
+
+void
+Group::addStatGroup(const char *name, Group *block)
+{
+ assert(statGroups.find(name) == statGroups.end());
+
+ statGroups[name] = block;
+}
+
+void
+Group::mergeStatGroup(Group *block)
+{
+ mergedStatGroups.push_back(block);
+}
+
+const std::map<std::string, Group *> &
+Group::getStatGroups() const
+{
+ return statGroups;
+}
+
+const std::vector<Info *> &
+Group::getStats() const
+{
+ return stats;
+}
+
+} // namespace Stats