mem-ruby: Update stats of AbstractController and derived classes
This commit moves stats of AbstractController and its derived classes to a Stats::Group struct. Also, one of the controllers needs access to the ruby system profiler stats, and Profiler's stats is now made public as a result. Change-Id: Ibe04e33a6cf09b453564592d29293b354d0d33c9 Signed-off-by: Hoa Nguyen <hoanguyen@ucdavis.edu> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/38075 Reviewed-by: Jason Lowe-Power <power.jg@gmail.com> Maintainer: Jason Lowe-Power <power.jg@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -185,6 +185,8 @@ class Profiler
|
||||
const bool m_all_instructions;
|
||||
const uint32_t m_num_vnets;
|
||||
|
||||
|
||||
public:
|
||||
ProfilerStats rubyProfilerStats;
|
||||
};
|
||||
|
||||
|
||||
@@ -56,7 +56,8 @@ AbstractController::AbstractController(const Params &p)
|
||||
m_buffer_size(p.buffer_size), m_recycle_latency(p.recycle_latency),
|
||||
m_mandatory_queue_latency(p.mandatory_queue_latency),
|
||||
memoryPort(csprintf("%s.memory", name()), this),
|
||||
addrRanges(p.addr_ranges.begin(), p.addr_ranges.end())
|
||||
addrRanges(p.addr_ranges.begin(), p.addr_ranges.end()),
|
||||
stats(this)
|
||||
{
|
||||
if (m_version == 0) {
|
||||
// Combine the statistics from all controllers
|
||||
@@ -68,11 +69,11 @@ AbstractController::AbstractController(const Params &p)
|
||||
void
|
||||
AbstractController::init()
|
||||
{
|
||||
m_delayHistogram.init(10);
|
||||
stats.m_delayHistogram.init(10);
|
||||
uint32_t size = Network::getNumberOfVirtualNetworks();
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
m_delayVCHistogram.push_back(new Stats::Histogram());
|
||||
m_delayVCHistogram[i]->init(10);
|
||||
stats.m_delayVCHistogram.push_back(new Stats::Histogram(this));
|
||||
stats.m_delayVCHistogram[i]->init(10);
|
||||
}
|
||||
|
||||
if (getMemReqQueue()) {
|
||||
@@ -106,10 +107,10 @@ AbstractController::init()
|
||||
void
|
||||
AbstractController::resetStats()
|
||||
{
|
||||
m_delayHistogram.reset();
|
||||
stats.m_delayHistogram.reset();
|
||||
uint32_t size = Network::getNumberOfVirtualNetworks();
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
m_delayVCHistogram[i]->reset();
|
||||
stats.m_delayVCHistogram[i]->reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,19 +118,14 @@ void
|
||||
AbstractController::regStats()
|
||||
{
|
||||
ClockedObject::regStats();
|
||||
|
||||
m_fully_busy_cycles
|
||||
.name(name() + ".fully_busy_cycles")
|
||||
.desc("cycles for which number of transistions == max transitions")
|
||||
.flags(Stats::nozero);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractController::profileMsgDelay(uint32_t virtualNetwork, Cycles delay)
|
||||
{
|
||||
assert(virtualNetwork < m_delayVCHistogram.size());
|
||||
m_delayHistogram.sample(delay);
|
||||
m_delayVCHistogram[virtualNetwork]->sample(delay);
|
||||
assert(virtualNetwork < stats.m_delayVCHistogram.size());
|
||||
stats.m_delayHistogram.sample(delay);
|
||||
stats.m_delayVCHistogram[virtualNetwork]->sample(delay);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -423,3 +419,17 @@ AbstractController::MemoryPort::MemoryPort(const std::string &_name,
|
||||
: RequestPort(_name, _controller, id), controller(_controller)
|
||||
{
|
||||
}
|
||||
|
||||
AbstractController::
|
||||
ControllerStats::ControllerStats(Stats::Group *parent)
|
||||
: Stats::Group(parent),
|
||||
m_fully_busy_cycles(this, "fully_busy_cycles",
|
||||
"cycles for which number of transistions == max "
|
||||
"transitions"),
|
||||
m_delayHistogram(this, "delay_histogram")
|
||||
{
|
||||
m_fully_busy_cycles
|
||||
.flags(Stats::nozero);
|
||||
m_delayHistogram
|
||||
.flags(Stats::nozero);
|
||||
}
|
||||
|
||||
@@ -151,9 +151,9 @@ class AbstractController : public ClockedObject, public Consumer
|
||||
MachineID getMachineID() const { return m_machineID; }
|
||||
RequestorID getRequestorId() const { return m_id; }
|
||||
|
||||
Stats::Histogram& getDelayHist() { return m_delayHistogram; }
|
||||
Stats::Histogram& getDelayHist() { return stats.m_delayHistogram; }
|
||||
Stats::Histogram& getDelayVCHist(uint32_t index)
|
||||
{ return *(m_delayVCHistogram[index]); }
|
||||
{ return *(stats.m_delayVCHistogram[index]); }
|
||||
|
||||
bool respondsTo(Addr addr)
|
||||
{
|
||||
@@ -204,14 +204,6 @@ class AbstractController : public ClockedObject, public Consumer
|
||||
std::unordered_map<Addr, TransMapPair> m_inTrans;
|
||||
std::unordered_map<Addr, TransMapPair> m_outTrans;
|
||||
|
||||
// Initialized by the SLICC compiler for all combinations of event and
|
||||
// states. Only histograms with samples will appear in the stats
|
||||
std::vector<std::vector<std::vector<Stats::Histogram*>>> m_inTransLatHist;
|
||||
|
||||
// Initialized by the SLICC compiler for all events.
|
||||
// Only histograms with samples will appear in the stats.
|
||||
std::vector<Stats::Histogram*> m_outTransLatHist;
|
||||
|
||||
/**
|
||||
* Profiles an event that initiates a protocol transactions for a specific
|
||||
* line (e.g. events triggered by incoming request messages).
|
||||
@@ -241,10 +233,10 @@ class AbstractController : public ClockedObject, public Consumer
|
||||
{
|
||||
auto iter = m_inTrans.find(addr);
|
||||
assert(iter != m_inTrans.end());
|
||||
m_inTransLatHist[iter->second.transaction]
|
||||
[iter->second.state]
|
||||
[(unsigned)finalState]->sample(
|
||||
ticksToCycles(curTick() - iter->second.time));
|
||||
stats.m_inTransLatHist[iter->second.transaction]
|
||||
[iter->second.state]
|
||||
[(unsigned)finalState]->sample(
|
||||
ticksToCycles(curTick() - iter->second.time));
|
||||
m_inTrans.erase(iter);
|
||||
}
|
||||
|
||||
@@ -272,7 +264,7 @@ class AbstractController : public ClockedObject, public Consumer
|
||||
{
|
||||
auto iter = m_outTrans.find(addr);
|
||||
assert(iter != m_outTrans.end());
|
||||
m_outTransLatHist[iter->second.transaction]->sample(
|
||||
stats.m_outTransLatHist[iter->second.transaction]->sample(
|
||||
ticksToCycles(curTick() - iter->second.time));
|
||||
m_outTrans.erase(iter);
|
||||
}
|
||||
@@ -308,15 +300,6 @@ class AbstractController : public ClockedObject, public Consumer
|
||||
Cycles m_recycle_latency;
|
||||
const Cycles m_mandatory_queue_latency;
|
||||
|
||||
//! Counter for the number of cycles when the transitions carried out
|
||||
//! were equal to the maximum allowed
|
||||
Stats::Scalar m_fully_busy_cycles;
|
||||
|
||||
//! Histogram for profiling delay for the messages this controller
|
||||
//! cares for
|
||||
Stats::Histogram m_delayHistogram;
|
||||
std::vector<Stats::Histogram *> m_delayVCHistogram;
|
||||
|
||||
/**
|
||||
* Port that forwards requests and receives responses from the
|
||||
* memory controller.
|
||||
@@ -363,6 +346,30 @@ class AbstractController : public ClockedObject, public Consumer
|
||||
|
||||
NetDest downstreamDestinations;
|
||||
|
||||
public:
|
||||
struct ControllerStats : public Stats::Group
|
||||
{
|
||||
ControllerStats(Stats::Group *parent);
|
||||
|
||||
// Initialized by the SLICC compiler for all combinations of event and
|
||||
// states. Only histograms with samples will appear in the stats
|
||||
std::vector<std::vector<std::vector<Stats::Histogram*>>>
|
||||
m_inTransLatHist;
|
||||
|
||||
// Initialized by the SLICC compiler for all events.
|
||||
// Only histograms with samples will appear in the stats.
|
||||
std::vector<Stats::Histogram*> m_outTransLatHist;
|
||||
|
||||
//! Counter for the number of cycles when the transitions carried out
|
||||
//! were equal to the maximum allowed
|
||||
Stats::Scalar m_fully_busy_cycles;
|
||||
|
||||
//! Histogram for profiling delay for the messages this controller
|
||||
//! cares for
|
||||
Stats::Histogram m_delayHistogram;
|
||||
std::vector<Stats::Histogram *> m_delayVCHistogram;
|
||||
} stats;
|
||||
|
||||
};
|
||||
|
||||
#endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__
|
||||
|
||||
@@ -815,13 +815,20 @@ $c_ident::regStats()
|
||||
{
|
||||
AbstractController::regStats();
|
||||
|
||||
// For each type of controllers, one controller of that type is picked
|
||||
// to aggregate stats of all controllers of that type.
|
||||
if (m_version == 0) {
|
||||
|
||||
Profiler *profiler = params().ruby_system->getProfiler();
|
||||
Stats::Group *profilerStatsPtr = &profiler->rubyProfilerStats;
|
||||
|
||||
for (${ident}_Event event = ${ident}_Event_FIRST;
|
||||
event < ${ident}_Event_NUM; ++event) {
|
||||
Stats::Vector *t = new Stats::Vector();
|
||||
std::string stat_name =
|
||||
"${c_ident}." + ${ident}_Event_to_string(event);
|
||||
Stats::Vector *t =
|
||||
new Stats::Vector(profilerStatsPtr, stat_name.c_str());
|
||||
t->init(m_num_controllers);
|
||||
t->name(params().ruby_system->name() + ".${c_ident}." +
|
||||
${ident}_Event_to_string(event));
|
||||
t->flags(Stats::pdf | Stats::total | Stats::oneline |
|
||||
Stats::nozero);
|
||||
|
||||
@@ -835,13 +842,12 @@ $c_ident::regStats()
|
||||
|
||||
for (${ident}_Event event = ${ident}_Event_FIRST;
|
||||
event < ${ident}_Event_NUM; ++event) {
|
||||
|
||||
Stats::Vector *t = new Stats::Vector();
|
||||
std::string stat_name = "${c_ident}." +
|
||||
${ident}_State_to_string(state) +
|
||||
"." + ${ident}_Event_to_string(event);
|
||||
Stats::Vector *t =
|
||||
new Stats::Vector(profilerStatsPtr, stat_name.c_str());
|
||||
t->init(m_num_controllers);
|
||||
t->name(params().ruby_system->name() + ".${c_ident}." +
|
||||
${ident}_State_to_string(state) +
|
||||
"." + ${ident}_Event_to_string(event));
|
||||
|
||||
t->flags(Stats::pdf | Stats::total | Stats::oneline |
|
||||
Stats::nozero);
|
||||
transVec[state].push_back(t);
|
||||
@@ -850,29 +856,30 @@ $c_ident::regStats()
|
||||
}
|
||||
for (${ident}_Event event = ${ident}_Event_FIRST;
|
||||
event < ${ident}_Event_NUM; ++event) {
|
||||
Stats::Histogram* t = new Stats::Histogram;
|
||||
m_outTransLatHist.push_back(t);
|
||||
std::string stat_name =
|
||||
"outTransLatHist." + ${ident}_Event_to_string(event);
|
||||
Stats::Histogram* t = new Stats::Histogram(&stats, stat_name.c_str());
|
||||
stats.m_outTransLatHist.push_back(t);
|
||||
t->init(5);
|
||||
t->name(name() + ".outTransLatHist." +
|
||||
${ident}_Event_to_string(event));
|
||||
t->flags(Stats::pdf | Stats::total |
|
||||
Stats::oneline | Stats::nozero);
|
||||
}
|
||||
for (${ident}_Event event = ${ident}_Event_FIRST;
|
||||
event < ${ident}_Event_NUM; ++event) {
|
||||
m_inTransLatHist.emplace_back();
|
||||
stats.m_inTransLatHist.emplace_back();
|
||||
for (${ident}_State initial_state = ${ident}_State_FIRST;
|
||||
initial_state < ${ident}_State_NUM; ++initial_state) {
|
||||
m_inTransLatHist.back().emplace_back();
|
||||
stats.m_inTransLatHist.back().emplace_back();
|
||||
for (${ident}_State final_state = ${ident}_State_FIRST;
|
||||
final_state < ${ident}_State_NUM; ++final_state) {
|
||||
Stats::Histogram* t = new Stats::Histogram;
|
||||
m_inTransLatHist.back().back().push_back(t);
|
||||
std::string stat_name = "inTransLatHist." +
|
||||
${ident}_Event_to_string(event) + "." +
|
||||
${ident}_State_to_string(initial_state) + "." +
|
||||
${ident}_State_to_string(final_state);
|
||||
Stats::Histogram* t =
|
||||
new Stats::Histogram(&stats, stat_name.c_str());
|
||||
stats.m_inTransLatHist.back().back().push_back(t);
|
||||
t->init(5);
|
||||
t->name(name() + ".inTransLatHist." +
|
||||
${ident}_Event_to_string(event) + "." +
|
||||
${ident}_State_to_string(initial_state) + "." +
|
||||
${ident}_State_to_string(final_state));
|
||||
t->flags(Stats::pdf | Stats::total |
|
||||
Stats::oneline | Stats::nozero);
|
||||
}
|
||||
@@ -1231,7 +1238,7 @@ ${ident}_Controller::wakeup()
|
||||
assert(counter <= m_transitions_per_cycle);
|
||||
if (counter == m_transitions_per_cycle) {
|
||||
// Count how often we are fully utilized
|
||||
m_fully_busy_cycles++;
|
||||
stats.m_fully_busy_cycles++;
|
||||
|
||||
// Wakeup in another cycle and try again
|
||||
scheduleEvent(Cycles(1));
|
||||
|
||||
Reference in New Issue
Block a user