stats β Statistics Framework
A comprehensive framework for declaring, collecting, and outputting performance counters, distributions, histograms, and derived formulas across all gem5 components.
📚 What is this & why does it exist?
π‘ Think of it likeβ¦The stats module is like the instrumentation panel in a nuclear power plant control room. Every reactor (CPU), cooling system (Cache Hierarchy | gem5 Wiki" href="../../mem_doc/cache/index.html">cache), and power line (bus) has sensors feeding real-time readings to the panel. Some sensors are Atomic and Timing Simple CPUs β gem5 Wiki" href="../../cpu_doc/simple/index.html">simple gauges (Scalar), some are multi-channel (Vector), some show distributions (Distribution), and some compute derived values from other readings (Formula). At reporting time, the entire panel is photographed (dump()) to a stats file.
Architecture Overview
The statistics framework is organized around Group objects that own collections of Info-backed statistics. Since SimObject inherits from statistics::Group, every simulated component automatically participates in the stats hierarchy.
graph TB
Group["statistics::Group\n(owns stats)"]
SimObject["SimObject\n(inherits Group)"]
Info["statistics::Info\n(metadata base)"]
Scalar["Scalar\n(single counter)"]
Vector["Vector\n(indexed counters)"]
Dist["Distribution\n(histogram)"]
Formula["Formula\n(derived expression)"]
Histogram["Histogram\n(auto-binning)"]
Output["Output\n(text, JSON, HDF5)"]
Group --> SimObject
Group --> Info
Info --> Scalar
Info --> Vector
Info --> Dist
Info --> Formula
Info --> Histogram
Group -->|"dump()"| Output
Statistic Types
Scalar
The simplest statistic β a single numeric counter. Used for counting events (instructions committed, cache misses, etc.).
namespace statistics {
class Scalar : public DataWrap<Scalar, ScalarInfo>
{
Counter data;
public:
void operator++();
void operator++(int);
void operator--();
void operator--(int);
void operator+=(Counter v);
void operator-=(Counter v);
Counter value() const { return data; }
// Chain initialization
Scalar &name(const std::string &n);
Scalar &desc(const std::string &d);
Scalar &precision(int p);
Scalar &flags(Flags f);
};
} // namespace statistics
Vector
An indexed array of counters. Used for per-thread, per-bank, or per-category counting.
class Vector : public DataWrap<Vector, VectorInfo>
{
std::vector<Counter> data;
public:
// Resize and access
Vector &init(size_t size);
ScalarProxy operator[](size_t index);
// Naming sub-stats
Vector &subname(size_t i, const std::string &name);
Vector &subdesc(size_t i, const std::string &desc);
size_t size() const;
};
// Usage:
// stats.memAccess.init(4)
// .subname(0, "read").subname(1, "write")
// .subname(2, "ifetch").subname(3, "prefetch");
Distribution
Tracks the distribution of sampled values across fixed-width bins. Essential for latency distributions, queue depth analysis, and similar metrics.
class Distribution : public DataWrap<Distribution, DistInfo>
{
public:
// Initialize with min, max, bucket_size
Distribution &init(Counter min, Counter max, Counter bkt);
void sample(Counter val, int number = 1);
Counter min_val;
Counter max_val;
Counter bucket_size;
Counter underflow;
Counter overflow;
std::vector<Counter> cvec; // Bucket counts
};
// Example: track memory access latency
// latencyDist.init(0, 1000, 10) β 0-1000 cycles, 10-cycle buckets
Histogram
Similar to Distribution but uses logarithmically-scaled or automatically-sized bins. Better for data with unknown range.
class Histogram : public DataWrap<Histogram, HistInfo>
{
public:
Histogram &init(size_t buckets); // Number of buckets
void sample(Counter val, int number = 1);
// Auto-grows: doubles bucket width when all buckets filled
void grow_up();
void grow_out();
size_t logs; // Log base for bucket sizes
};
Formula
Computed statistics derived from other stats using arithmetic expressions. Evaluated at dump time, not during simulation.
class Formula : public DataWrap<Formula, FormulaInfo>
{
public:
// Build from expression tree
Formula &operator=(const Temp &r);
const Formula &operator+=(const Temp &r);
// Compute current value
Result total() const;
VResult result() const;
};
// Usage in regStats():
// ipc.name("ipc").desc("Instructions per cycle")
// = committedInsts / simCycles;
Vector2d
A 2D matrix of counters. Used for cross-product statistics like per-thread-per-type event counts.
class Vector2d : public DataWrap<Vector2d, Vector2dInfo>
{
public:
Vector2d &init(size_t x, size_t y);
ScalarProxy operator()(size_t x, size_t y);
Vector2d &ysubname(size_t i, const std::string &name);
};
Statistics Group
The Group class organizes statistics hierarchically. Each System & Standard Library Β· gem5 Wiki" class="xref">SimObject is a Group, and Groups can contain sub-Groups for modular organization.
class Group
{
public:
Group(Group *parent, const char *name = nullptr);
// Register a child group
void addStatGroup(const char *name, Group *group);
// Called during initialization
virtual void regStats();
virtual void resetStats();
// Merge another group's stats
void mergeStatGroup(Group *group);
// Stat registration (called by stat constructors)
void addStat(Info *info);
};
// SimObject inherits from Group:
// class SimObject : public ... , public statistics::Group
Statistics Lifecycle
sequenceDiagram
participant Py as Python Config
participant SO as SimObject
participant Stats as Stats System
participant Out as Output Backend
Py->>SO: instantiate()
SO->>Stats: regStats()
Stats->>Stats: Register all Info objects
Note over Stats: Simulation runs...
SO->>Stats: Increment/sample stats
Py->>Stats: dump()
Stats->>Out: Visit all registered stats
Out->>Out: Format and write (stats.txt)
Py->>Stats: reset()
Stats->>Stats: Zero all counters
Note over Stats: Continue simulation...
Py->>Stats: dump()
Stats->>Out: Write delta stats
π Narrated Walkthrough: Defining and Using Statistics
- Declaration β In your SimObject's header, declare stat members as
statistics::Scalar,statistics::Vector, etc. inside a nestedStatsstruct inheriting fromstatistics::Group. - Registration β Override
regStats(). Call each stat's.name(),.desc(), and.init()chain. Stats auto-register with their parent Group. - Incrementing β During simulation, use
++stat,stat += value, orstat.sample(val)to record data. These are lightweight inline operations. - Formula Definition β In
regStats(), define computed stats:ipc = committedInsts / simCycles;. The expression tree is stored, not evaluated. - Dumping β When
m5.stats.dump()is called (periodically or at exit), all stats are visited. Formulas are evaluated. Output is written tostats.txtby the text output backend. - Resetting β
m5.stats.reset()zeros all counters, enabling interval-based statistics collection.
Output Backends
Pipeline β gem5 Wiki" class="xref">Statistics can be output in multiple formats simultaneously:
| Backend | File | Description |
|---|---|---|
| Text | stats.txt | Human-readable key=value format (default) |
| JSON | stats.json | Machine-parseable JSON output |
| HDF5 | stats.h5 | Hierarchical binary format for large-scale analysis |
Text Output Example
---------- Begin Simulation Statistics ----------
system.cpu.committedInsts 1000000
system.cpu.committedOps 1523847
system.cpu.numCycles 2500000
system.cpu.ipc 0.400000
system.cpu.cpi 2.500000
system.l2cache.overallMissRate::total 0.032456
system.l2cache.overallAvgMissLatency::total 185.234
---------- End Simulation Statistics ----------
Statistic Flags
| Flag | Effect |
|---|---|
none | Default β always printed |
nozero | Don't print if value is zero |
nonan | Don't print if value is NaN |
total | Print total of vector elements |
dist | Print distribution details |
pdf | Print probability density function |
cdf | Print cumulative distribution function |
Complete Usage Example
class MyCache : public ClockedObject
{
struct MyCacheStats : public statistics::Group
{
MyCacheStats(MyCache *cache);
statistics::Scalar hits;
statistics::Scalar misses;
statistics::Formula missRate;
statistics::Vector accessesByType;
statistics::Distribution hitLatency;
} stats;
public:
MyCache(const Params &p)
: ClockedObject(p), stats(this) {}
};
MyCache::MyCacheStats::MyCacheStats(MyCache *cache)
: statistics::Group(cache, "cache_stats")
{
hits.name("hits").desc("Number of cache hits");
misses.name("misses").desc("Number of cache misses");
missRate.name("missRate").desc("Cache miss rate")
= misses / (hits + misses);
accessesByType.init(3)
.name("accessesByType")
.subname(0, "read")
.subname(1, "write")
.subname(2, "prefetch");
hitLatency.init(0, 100, 5)
.name("hitLatency")
.desc("Hit latency distribution (cycles)")
.flags(statistics::pdf | statistics::cdf);
}
Key Components Reference
| Component | Header | Purpose |
|---|---|---|
Group | group.hh | Hierarchical stat container (SimObject base) |
Info | info.hh | Metadata base for all statistics |
Scalar | statistics.hh | Single counter value |
Vector | statistics.hh | Indexed array of counters |
Vector2d | statistics.hh | 2D matrix of counters |
Distribution | statistics.hh | Fixed-bin distribution of sampled values |
Histogram | statistics.hh | Auto-growing histogram |
Formula | statistics.hh | Derived expression evaluated at dump time |
Output | output.hh | Abstract output backend interface |
Text | text.hh | Text file output backend |
Glossary
| Term | Definition |
|---|---|
| Counter | The underlying numeric type for statistics (typically double) |
| Result | The computed value of a statistic at dump time |
| Dump | The operation that writes all statistics to output files |
| Reset | Zeroing all counters to enable interval measurement |
| Formula | A derived statistic that computes its value from other statistics using arithmetic |
| Probability Density Function β fraction of samples in each bin | |
| CDF | Cumulative Distribution Function β running total of PDF |
| IPC | Instructions Per Cycle β the most common derived performance metric |