From 6a80d9f0aa2d6b5b187f135b7186f599e0b39901 Mon Sep 17 00:00:00 2001 From: Hoa Nguyen Date: Fri, 27 Nov 2020 02:41:24 -0800 Subject: [PATCH] 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 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/38075 Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power Tested-by: kokoro --- src/mem/ruby/profiler/Profiler.hh | 2 + .../slicc_interface/AbstractController.cc | 38 ++++++++----- .../slicc_interface/AbstractController.hh | 55 +++++++++++-------- src/mem/slicc/symbols/StateMachine.py | 51 +++++++++-------- 4 files changed, 86 insertions(+), 60 deletions(-) diff --git a/src/mem/ruby/profiler/Profiler.hh b/src/mem/ruby/profiler/Profiler.hh index 1c81eebcc..aa1548785 100644 --- a/src/mem/ruby/profiler/Profiler.hh +++ b/src/mem/ruby/profiler/Profiler.hh @@ -185,6 +185,8 @@ class Profiler const bool m_all_instructions; const uint32_t m_num_vnets; + + public: ProfilerStats rubyProfilerStats; }; diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc b/src/mem/ruby/slicc_interface/AbstractController.cc index ba2075a0d..4241d720a 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.cc +++ b/src/mem/ruby/slicc_interface/AbstractController.cc @@ -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); +} diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh index 8e19195dd..ce81de084 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.hh +++ b/src/mem/ruby/slicc_interface/AbstractController.hh @@ -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 m_inTrans; std::unordered_map 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>> m_inTransLatHist; - - // Initialized by the SLICC compiler for all events. - // Only histograms with samples will appear in the stats. - std::vector 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 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>> + m_inTransLatHist; + + // Initialized by the SLICC compiler for all events. + // Only histograms with samples will appear in the stats. + std::vector 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 m_delayVCHistogram; + } stats; + }; #endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__ diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py index c4601bb6d..63f2b4f16 100644 --- a/src/mem/slicc/symbols/StateMachine.py +++ b/src/mem/slicc/symbols/StateMachine.py @@ -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)); -- 2.30.2