diff options
author | Andreas Sandberg <andreas.sandberg@arm.com> | 2019-06-26 18:58:24 +0100 |
---|---|---|
committer | Andreas Sandberg <andreas.sandberg@arm.com> | 2019-08-29 09:01:38 +0000 |
commit | 6f38428abbe106d63318dd86bfa82a03b6b368ee (patch) | |
tree | fb0e758c120bf45d7c017f97396c66cba1bb4792 /src/base/statistics.hh | |
parent | 09281876a77c8ec66560bc91715421491c335c6b (diff) | |
download | gem5-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/statistics.hh')
-rw-r--r-- | src/base/statistics.hh | 204 |
1 files changed, 164 insertions, 40 deletions
diff --git a/src/base/statistics.hh b/src/base/statistics.hh index 6ddf7ff17..f4fa123e9 100644 --- a/src/base/statistics.hh +++ b/src/base/statistics.hh @@ -1,4 +1,16 @@ /* + * 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. + * * Copyright (c) 2003-2005 The Regents of The University of Michigan * Copyright (c) 2017, Centre National de la Recherche Scientifique * All rights reserved. @@ -63,6 +75,7 @@ #include <string> #include <vector> +#include "base/stats/group.hh" #include "base/stats/info.hh" #include "base/stats/output.hh" #include "base/stats/types.hh" @@ -172,9 +185,12 @@ struct StorageParams class InfoAccess { + private: + Info *_info; + protected: /** Set up an info class for this statistic */ - void setInfo(Info *info); + void setInfo(Group *parent, Info *info); /** Save Storage class parameters if any */ void setParams(const StorageParams *params); /** Save Storage class parameters if any */ @@ -186,6 +202,9 @@ class InfoAccess const Info *info() const; public: + InfoAccess() + : _info(nullptr) {}; + /** * Reset the stat to the default state. */ @@ -228,21 +247,27 @@ class DataWrap : public InfoAccess return safe_cast<const Info *>(InfoAccess::info()); } - protected: - /** - * Copy constructor, copies are not allowed. - */ - DataWrap(const DataWrap &stat) = delete; + public: + DataWrap() = delete; + DataWrap(const DataWrap &) = delete; + DataWrap &operator=(const DataWrap &) = delete; - /** - * Can't copy stats. - */ - void operator=(const DataWrap &) {} - public: - DataWrap() + DataWrap(Group *parent, const char *name, const char *desc) { - this->setInfo(new Info(self())); + auto info = new Info(self()); + this->setInfo(parent, info); + + if (parent) + parent->addStat(info); + + if (name) { + info->setName(name); + info->flags.set(display); + } + + if (desc) + info->desc = desc; } /** @@ -335,13 +360,9 @@ class DataWrapVec : public DataWrap<Derived, InfoProxyType> public: typedef InfoProxyType<Derived> Info; - DataWrapVec() - {} - - DataWrapVec(const DataWrapVec &ref) - {} - - void operator=(const DataWrapVec &) + DataWrapVec(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : DataWrap<Derived, InfoProxyType>(parent, name, desc) {} // The following functions are specific to vectors. If you use them @@ -420,6 +441,11 @@ class DataWrapVec2d : public DataWrapVec<Derived, InfoProxyType> public: typedef InfoProxyType<Derived> Info; + DataWrapVec2d(Group *parent, const char *name, const char *desc) + : DataWrapVec<Derived, InfoProxyType>(parent, name, desc) + { + } + /** * @warning This makes the assumption that if you're gonna subnames a 2d * vector, you're subnaming across all y @@ -677,7 +703,9 @@ class ScalarBase : public DataWrap<Derived, ScalarInfoProxy> Counter value() const { return data()->value(); } public: - ScalarBase() + ScalarBase(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : DataWrap<Derived, ScalarInfoProxy>(parent, name, desc) { this->doInit(); } @@ -807,7 +835,12 @@ class ValueBase : public DataWrap<Derived, ScalarInfoProxy> ProxyInfo *proxy; public: - ValueBase() : proxy(NULL) { } + ValueBase(Group *parent, const char *name, const char *desc) + : DataWrap<Derived, ScalarInfoProxy>(parent, name, desc), + proxy(NULL) + { + } + ~ValueBase() { if (proxy) delete proxy; } template <class T> @@ -1095,8 +1128,9 @@ class VectorBase : public DataWrapVec<Derived, VectorInfoProxy> } public: - VectorBase() - : storage(nullptr), _size(0) + VectorBase(Group *parent, const char *name, const char *desc) + : DataWrapVec<Derived, VectorInfoProxy>(parent, name, desc), + storage(nullptr), _size(0) {} ~VectorBase() @@ -1235,8 +1269,9 @@ class Vector2dBase : public DataWrapVec2d<Derived, Vector2dInfoProxy> const Storage *data(off_type index) const { return &storage[index]; } public: - Vector2dBase() - : x(0), y(0), _size(0), storage(nullptr) + Vector2dBase(Group *parent, const char *name, const char *desc) + : DataWrapVec2d<Derived, Vector2dInfoProxy>(parent, name, desc), + x(0), y(0), _size(0), storage(nullptr) {} ~Vector2dBase() @@ -1851,7 +1886,10 @@ class DistBase : public DataWrap<Derived, DistInfoProxy> } public: - DistBase() { } + DistBase(Group *parent, const char *name, const char *desc) + : DataWrap<Derived, DistInfoProxy>(parent, name, desc) + { + } /** * Add a value to the distribtion n times. Calls sample on the storage @@ -1945,8 +1983,9 @@ class VectorDistBase : public DataWrapVec<Derived, VectorDistInfoProxy> } public: - VectorDistBase() - : storage(NULL) + VectorDistBase(Group *parent, const char *name, const char *desc) + : DataWrapVec<Derived, VectorDistInfoProxy>(parent, name, desc), + storage(NULL) {} ~VectorDistBase() @@ -2472,6 +2511,12 @@ class Scalar : public ScalarBase<Scalar, StatStor> { public: using ScalarBase<Scalar, StatStor>::operator=; + + Scalar(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : ScalarBase<Scalar, StatStor>(parent, name, desc) + { + } }; /** @@ -2482,10 +2527,22 @@ class Average : public ScalarBase<Average, AvgStor> { public: using ScalarBase<Average, AvgStor>::operator=; + + Average(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : ScalarBase<Average, AvgStor>(parent, name, desc) + { + } }; class Value : public ValueBase<Value> { + public: + Value(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : ValueBase<Value>(parent, name, desc) + { + } }; /** @@ -2494,6 +2551,12 @@ class Value : public ValueBase<Value> */ class Vector : public VectorBase<Vector, StatStor> { + public: + Vector(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : VectorBase<Vector, StatStor>(parent, name, desc) + { + } }; /** @@ -2502,6 +2565,12 @@ class Vector : public VectorBase<Vector, StatStor> */ class AverageVector : public VectorBase<AverageVector, AvgStor> { + public: + AverageVector(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : VectorBase<AverageVector, AvgStor>(parent, name, desc) + { + } }; /** @@ -2510,6 +2579,12 @@ class AverageVector : public VectorBase<AverageVector, AvgStor> */ class Vector2d : public Vector2dBase<Vector2d, StatStor> { + public: + Vector2d(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : Vector2dBase<Vector2d, StatStor>(parent, name, desc) + { + } }; /** @@ -2519,6 +2594,12 @@ class Vector2d : public Vector2dBase<Vector2d, StatStor> class Distribution : public DistBase<Distribution, DistStor> { public: + Distribution(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : DistBase<Distribution, DistStor>(parent, name, desc) + { + } + /** * Set the parameters of this distribution. @sa DistStor::Params * @param min The minimum value of the distribution. @@ -2550,6 +2631,12 @@ class Distribution : public DistBase<Distribution, DistStor> class Histogram : public DistBase<Histogram, HistStor> { public: + Histogram(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : DistBase<Histogram, HistStor>(parent, name, desc) + { + } + /** * Set the parameters of this histogram. @sa HistStor::Params * @param size The number of buckets in the histogram @@ -2576,7 +2663,9 @@ class StandardDeviation : public DistBase<StandardDeviation, SampleStor> /** * Construct and initialize this distribution. */ - StandardDeviation() + StandardDeviation(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : DistBase<StandardDeviation, SampleStor>(parent, name, desc) { SampleStor::Params *params = new SampleStor::Params; this->doInit(); @@ -2594,7 +2683,9 @@ class AverageDeviation : public DistBase<AverageDeviation, AvgSampleStor> /** * Construct and initialize this distribution. */ - AverageDeviation() + AverageDeviation(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : DistBase<AverageDeviation, AvgSampleStor>(parent, name, desc) { AvgSampleStor::Params *params = new AvgSampleStor::Params; this->doInit(); @@ -2609,6 +2700,12 @@ class AverageDeviation : public DistBase<AverageDeviation, AvgSampleStor> class VectorDistribution : public VectorDistBase<VectorDistribution, DistStor> { public: + VectorDistribution(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : VectorDistBase<VectorDistribution, DistStor>(parent, name, desc) + { + } + /** * Initialize storage and parameters for this distribution. * @param size The size of the vector (the number of distributions). @@ -2639,6 +2736,13 @@ class VectorStandardDeviation : public VectorDistBase<VectorStandardDeviation, SampleStor> { public: + VectorStandardDeviation(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : VectorDistBase<VectorStandardDeviation, SampleStor>(parent, name, + desc) + { + } + /** * Initialize storage for this distribution. * @param size The size of the vector. @@ -2662,6 +2766,13 @@ class VectorAverageDeviation : public VectorDistBase<VectorAverageDeviation, AvgSampleStor> { public: + VectorAverageDeviation(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : VectorDistBase<VectorAverageDeviation, AvgSampleStor>(parent, name, + desc) + { + } + /** * Initialize storage for this distribution. * @param size The size of the vector. @@ -2753,7 +2864,10 @@ class SparseHistBase : public DataWrap<Derived, SparseHistInfoProxy> } public: - SparseHistBase() { } + SparseHistBase(Group *parent, const char *name, const char *desc) + : DataWrap<Derived, SparseHistInfoProxy>(parent, name, desc) + { + } /** * Add a value to the distribtion n times. Calls sample on the storage @@ -2870,6 +2984,12 @@ class SparseHistStor class SparseHistogram : public SparseHistBase<SparseHistogram, SparseHistStor> { public: + SparseHistogram(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : SparseHistBase<SparseHistogram, SparseHistStor>(parent, name, desc) + { + } + /** * Set the parameters of this histogram. @sa HistStor::Params * @param size The number of buckets in the histogram @@ -2902,21 +3022,25 @@ class Formula : public DataWrapVec<Formula, FormulaInfoProxy> /** * Create and initialize thie formula, and register it with the database. */ - Formula(); + Formula(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr); - /** - * Create a formula with the given root node, register it with the - * database. - * @param r The root of the expression tree. - */ - Formula(Temp r); + Formula(Group *parent, const char *name, const char *desc, + const Temp &r); /** * Set an unitialized Formula to the given root. * @param r The root of the expression tree. * @return a reference to this formula. */ - const Formula &operator=(Temp r); + const Formula &operator=(const Temp &r); + + template<typename T> + const Formula &operator=(const T &v) + { + *this = Temp(v); + return *this; + } /** * Add the given tree to the existing one. |