summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/ruby/profiler/MemCntrlProfiler.cc215
-rw-r--r--src/mem/ruby/profiler/MemCntrlProfiler.hh41
-rw-r--r--src/mem/ruby/slicc_interface/AbstractController.cc6
-rw-r--r--src/mem/ruby/slicc_interface/AbstractController.hh29
-rw-r--r--src/mem/ruby/system/MemoryControl.hh3
-rw-r--r--src/mem/ruby/system/RubyMemoryControl.cc19
-rw-r--r--src/mem/ruby/system/RubyMemoryControl.hh3
-rw-r--r--src/mem/slicc/ast/MachineAST.py4
-rw-r--r--src/mem/slicc/symbols/StateMachine.py404
9 files changed, 339 insertions, 385 deletions
diff --git a/src/mem/ruby/profiler/MemCntrlProfiler.cc b/src/mem/ruby/profiler/MemCntrlProfiler.cc
index 632842a2e..0cfc1e629 100644
--- a/src/mem/ruby/profiler/MemCntrlProfiler.cc
+++ b/src/mem/ruby/profiler/MemCntrlProfiler.cc
@@ -37,11 +37,6 @@ MemCntrlProfiler::MemCntrlProfiler(const string& description,
m_banks_per_rank = banks_per_rank;
m_ranks_per_dimm = ranks_per_dimm;
m_dimms_per_channel = dimms_per_channel;
-
- int totalBanks = banks_per_rank * ranks_per_dimm * dimms_per_channel;
- m_memBankCount.resize(totalBanks);
-
- clearStats();
}
MemCntrlProfiler::~MemCntrlProfiler()
@@ -49,87 +44,6 @@ MemCntrlProfiler::~MemCntrlProfiler()
}
void
-MemCntrlProfiler::printStats(ostream& out) const
-{
- if (!m_memReq && !m_memRefresh) {
- out << "Memory Controller: " << m_description
- << " no stats recorded." << endl
- << endl
- << endl;
- return;
- }
-
- // if there's a memory controller at all
- uint64 total_stalls = m_memInputQ + m_memBankQ + m_memWaitCycles;
- double stallsPerReq = total_stalls * 1.0 / m_memReq;
- out << "Memory controller: " << m_description << ":" << endl;
-
- // does not include refreshes
- out << " memory_total_requests: " << m_memReq << endl;
- out << " memory_reads: " << m_memRead << endl;
- out << " memory_writes: " << m_memWrite << endl;
- out << " memory_refreshes: " << m_memRefresh << endl;
- out << " memory_total_request_delays: " << total_stalls << endl;
- out << " memory_delays_per_request: " << stallsPerReq << endl;
- out << " memory_delays_in_input_queue: " << m_memInputQ << endl;
- out << " memory_delays_behind_head_of_bank_queue: "
- << m_memBankQ << endl;
- out << " memory_delays_stalled_at_head_of_bank_queue: "
- << m_memWaitCycles << endl;
-
- // Note: The following "memory stalls" entries are a breakdown of
- // the cycles which already showed up in m_memWaitCycles. The
- // order is significant; it is the priority of attributing the
- // cycles. For example, bank_busy is before arbitration because
- // if the bank was busy, we didn't even check arbitration.
- // Note: "not old enough" means that since we grouped waiting
- // heads-of-queues into batches to avoid starvation, a request in
- // a newer batch didn't try to arbitrate yet because there are
- // older requests waiting.
- out << " memory_stalls_for_bank_busy: " << m_memBankBusy << endl;
- out << " memory_stalls_for_random_busy: " << m_memRandBusy << endl;
- out << " memory_stalls_for_anti_starvation: " << m_memNotOld << endl;
- out << " memory_stalls_for_arbitration: " << m_memArbWait << endl;
- out << " memory_stalls_for_bus: " << m_memBusBusy << endl;
- out << " memory_stalls_for_tfaw: " << m_memTfawBusy << endl;
- out << " memory_stalls_for_read_write_turnaround: "
- << m_memReadWriteBusy << endl;
- out << " memory_stalls_for_read_read_turnaround: "
- << m_memDataBusBusy << endl;
- out << " accesses_per_bank: ";
-
- for (int bank = 0; bank < m_memBankCount.size(); bank++) {
- out << m_memBankCount[bank] << " ";
- }
- out << endl;
- out << endl;
-}
-
-void
-MemCntrlProfiler::clearStats()
-{
- m_memReq = 0;
- m_memBankBusy = 0;
- m_memBusBusy = 0;
- m_memTfawBusy = 0;
- m_memReadWriteBusy = 0;
- m_memDataBusBusy = 0;
- m_memRefresh = 0;
- m_memRead = 0;
- m_memWrite = 0;
- m_memWaitCycles = 0;
- m_memInputQ = 0;
- m_memBankQ = 0;
- m_memArbWait = 0;
- m_memRandBusy = 0;
- m_memNotOld = 0;
-
- for (int bank = 0; bank < m_memBankCount.size(); bank++) {
- m_memBankCount[bank] = 0;
- }
-}
-
-void
MemCntrlProfiler::profileMemReq(int bank)
{
m_memReq++;
@@ -220,4 +134,133 @@ MemCntrlProfiler::profileMemNotOld()
m_memNotOld++;
}
+void
+MemCntrlProfiler::regStats()
+{
+ m_memReq
+ .name(m_description + ".memReq")
+ .desc("Total number of memory requests")
+ .flags(Stats::nozero)
+ ;
+
+ m_memRead
+ .name(m_description + ".memRead")
+ .desc("Number of memory reads")
+ .flags(Stats::nozero)
+ ;
+
+ m_memWrite
+ .name(m_description + ".memWrite")
+ .desc("Number of memory writes")
+ .flags(Stats::nozero)
+ ;
+
+ m_memRefresh
+ .name(m_description + ".memRefresh")
+ .desc("Number of memory refreshes")
+ .flags(Stats::nozero)
+ ;
+
+ m_memInputQ
+ .name(m_description + ".memInputQ")
+ .desc("Delay in the input queue")
+ .flags(Stats::nozero)
+ ;
+
+ m_memBankQ
+ .name(m_description + ".memBankQ")
+ .desc("Delay behind the head of the bank queue")
+ .flags(Stats::nozero)
+ ;
+
+ m_memWaitCycles
+ .name(m_description + ".memWaitCycles")
+ .desc("Delay stalled at the head of the bank queue")
+ .flags(Stats::nozero)
+ ;
+
+ m_totalStalls
+ .name(m_description + ".totalStalls")
+ .desc("Total number of stall cycles")
+ .flags(Stats::nozero)
+ ;
+
+ m_totalStalls = m_memInputQ + m_memBankQ + m_memWaitCycles;
+
+ m_stallsPerReq
+ .name(m_description + ".stallsPerReq")
+ .desc("Expected number of stall cycles per request")
+ .flags(Stats::nozero)
+ ;
+
+ m_stallsPerReq = m_totalStalls / m_memReq;
+
+ // Note: The following "memory stalls" entries are a breakdown of
+ // the cycles which already showed up in m_memWaitCycles. The
+ // order is significant; it is the priority of attributing the
+ // cycles. For example, bank_busy is before arbitration because
+ // if the bank was busy, we didn't even check arbitration.
+ // Note: "not old enough" means that since we grouped waiting
+ // heads-of-queues into batches to avoid starvation, a request in
+ // a newer batch didn't try to arbitrate yet because there are
+ // older requests waiting.
+ m_memBankBusy
+ .name(m_description + ".memBankBusy")
+ .desc("memory stalls due to busy bank")
+ .flags(Stats::nozero)
+ ;
+
+ m_memRandBusy
+ .name(m_description + ".memRandBusy")
+ .desc("memory stalls due to busy random")
+ .flags(Stats::nozero)
+ ;
+
+ m_memNotOld
+ .name(m_description + ".memNotOld")
+ .desc("memory stalls due to anti starvation")
+ .flags(Stats::nozero)
+ ;
+
+ m_memArbWait
+ .name(m_description + ".memArbWait")
+ .desc("memory stalls due to arbitration")
+ .flags(Stats::nozero)
+ ;
+
+ m_memBusBusy
+ .name(m_description + ".memBusBusy")
+ .desc("memory stalls due to busy bus")
+ .flags(Stats::nozero)
+ ;
+
+ m_memTfawBusy
+ .name(m_description + ".memTfawBusy")
+ .desc("memory stalls for Tfaw")
+ .flags(Stats::nozero)
+ ;
+
+ m_memReadWriteBusy
+ .name(m_description + ".memReadWriteBusy")
+ .desc("memory stalls due to read write turnaround")
+ .flags(Stats::nozero)
+ ;
+
+ m_memDataBusBusy
+ .name(m_description + ".memDataBusBusy")
+ .desc("memory stalls due to read read turnaround")
+ .flags(Stats::nozero)
+ ;
+
+ int totalBanks = m_banks_per_rank * m_ranks_per_dimm * m_dimms_per_channel;
+ m_memBankCount
+ .init(totalBanks)
+ .name(m_description + ".memBankCount")
+ .desc("Number of accesses per bank")
+ .flags(Stats::pdf | Stats::total|Stats::oneline)
+ ;
+ for (int i = 0; i < totalBanks; i++) {
+ m_memBankCount.subname(i, "");
+ }
+}
diff --git a/src/mem/ruby/profiler/MemCntrlProfiler.hh b/src/mem/ruby/profiler/MemCntrlProfiler.hh
index a594e0d96..56e283f50 100644
--- a/src/mem/ruby/profiler/MemCntrlProfiler.hh
+++ b/src/mem/ruby/profiler/MemCntrlProfiler.hh
@@ -33,6 +33,7 @@
#include <string>
#include <vector>
+#include "base/statistics.hh"
#include "mem/ruby/common/TypeDefines.hh"
class MemCntrlProfiler
@@ -42,8 +43,7 @@ class MemCntrlProfiler
int ranks_per_dimm, int dimms_per_channel);
~MemCntrlProfiler();
- void printStats(std::ostream& out) const;
- void clearStats();
+ void regStats();
void profileMemReq(int bank);
void profileMemBankBusy();
@@ -69,22 +69,27 @@ private:
MemCntrlProfiler& operator=(const MemCntrlProfiler& obj);
std::string m_description;
- uint64 m_memReq;
- uint64 m_memBankBusy;
- uint64 m_memBusBusy;
- uint64 m_memTfawBusy;
- uint64 m_memReadWriteBusy;
- uint64 m_memDataBusBusy;
- uint64 m_memRefresh;
- uint64 m_memRead;
- uint64 m_memWrite;
- uint64 m_memWaitCycles;
- uint64 m_memInputQ;
- uint64 m_memBankQ;
- uint64 m_memArbWait;
- uint64 m_memRandBusy;
- uint64 m_memNotOld;
- std::vector<uint64> m_memBankCount;
+ Stats::Scalar m_memReq;
+ Stats::Scalar m_memRead;
+ Stats::Scalar m_memWrite;
+ Stats::Scalar m_memRefresh;
+
+ Stats::Scalar m_memWaitCycles;
+ Stats::Scalar m_memInputQ;
+ Stats::Scalar m_memBankQ;
+ Stats::Formula m_totalStalls;
+ Stats::Formula m_stallsPerReq;
+
+ Stats::Scalar m_memBankBusy;
+ Stats::Scalar m_memBusBusy;
+ Stats::Scalar m_memTfawBusy;
+ Stats::Scalar m_memReadWriteBusy;
+ Stats::Scalar m_memDataBusBusy;
+ Stats::Scalar m_memArbWait;
+ Stats::Scalar m_memRandBusy;
+ Stats::Scalar m_memNotOld;
+ Stats::Vector m_memBankCount;
+
int m_banks_per_rank;
int m_ranks_per_dimm;
int m_dimms_per_channel;
diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc b/src/mem/ruby/slicc_interface/AbstractController.cc
index 6e99a72bb..930f3a70f 100644
--- a/src/mem/ruby/slicc_interface/AbstractController.cc
+++ b/src/mem/ruby/slicc_interface/AbstractController.cc
@@ -40,6 +40,12 @@ AbstractController::AbstractController(const Params *p)
m_recycle_latency = p->recycle_latency;
m_number_of_TBEs = p->number_of_TBEs;
m_is_blocking = false;
+
+ if (m_version == 0) {
+ // Combine the statistics from all controllers
+ // of this particular type.
+ Stats::registerDumpCallback(new StatsCallback(this));
+ }
}
void
diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh
index e2471777b..079979bdf 100644
--- a/src/mem/ruby/slicc_interface/AbstractController.hh
+++ b/src/mem/ruby/slicc_interface/AbstractController.hh
@@ -32,6 +32,7 @@
#include <iostream>
#include <string>
+#include "base/callback.hh"
#include "mem/protocol/AccessPermission.hh"
#include "mem/ruby/buffers/MessageBuffer.hh"
#include "mem/ruby/common/Address.hh"
@@ -54,6 +55,7 @@ class AbstractController : public ClockedObject, public Consumer
AbstractController(const Params *p);
void init();
const Params *params() const { return (const Params *)_params; }
+
virtual MessageBuffer* getMandatoryQueue() const = 0;
virtual const int & getVersion() const = 0;
virtual const std::string toString() const = 0; // returns text version of
@@ -68,8 +70,9 @@ class AbstractController : public ClockedObject, public Consumer
virtual void print(std::ostream & out) const = 0;
virtual void printStats(std::ostream & out) const = 0;
virtual void wakeup() = 0;
- // virtual void dumpStats(std::ostream & out) = 0;
virtual void clearStats() = 0;
+ virtual void regStats() = 0;
+
virtual void recordCacheTrace(int cntrl, CacheRecorder* tr) = 0;
virtual Sequencer* getSequencer() const = 0;
@@ -86,6 +89,12 @@ class AbstractController : public ClockedObject, public Consumer
virtual void enqueuePrefetch(const Address&, const RubyRequestType&)
{ fatal("Prefetches not implemented!");}
+ //! Function for collating statistics from all the controllers of this
+ //! particular type. This function should only be called from the
+ //! version 0 of this controller type.
+ virtual void collateStats()
+ {fatal("collateStats() should be overridden!");}
+
public:
MachineID getMachineID() const { return m_machineID; }
uint64_t getFullyBusyCycles() const { return m_fully_busy_cycles; }
@@ -154,6 +163,24 @@ class AbstractController : public ClockedObject, public Consumer
//! cares for
Histogram m_delayHistogram;
std::vector<Histogram> m_delayVCHistogram;
+
+ //! Callback class used for collating statistics from all the
+ //! controller of this type.
+ class StatsCallback : public Callback
+ {
+ private:
+ AbstractController *ctr;
+
+ public:
+ virtual ~StatsCallback() {}
+
+ StatsCallback(AbstractController *_ctr)
+ : ctr(_ctr)
+ {
+ }
+
+ void process() {ctr->collateStats();}
+ };
};
#endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__
diff --git a/src/mem/ruby/system/MemoryControl.hh b/src/mem/ruby/system/MemoryControl.hh
index daa5b61fc..6dc32b661 100644
--- a/src/mem/ruby/system/MemoryControl.hh
+++ b/src/mem/ruby/system/MemoryControl.hh
@@ -75,9 +75,6 @@ class MemoryControl : public ClockedObject, public Consumer
virtual bool areNSlotsAvailable(int n) = 0; // infinite queue length
virtual void print(std::ostream& out) const = 0;
- virtual void clearStats() const = 0;
- virtual void printStats(std::ostream& out) const = 0;
-
virtual void regStats() {};
virtual const int getChannel(const physical_address_t addr) const = 0;
diff --git a/src/mem/ruby/system/RubyMemoryControl.cc b/src/mem/ruby/system/RubyMemoryControl.cc
index 5ffc60e2b..84126a8f5 100644
--- a/src/mem/ruby/system/RubyMemoryControl.cc
+++ b/src/mem/ruby/system/RubyMemoryControl.cc
@@ -221,6 +221,7 @@ RubyMemoryControl::init()
m_tfaw_count[i] = 0;
}
}
+
void
RubyMemoryControl::reset()
{
@@ -359,18 +360,6 @@ RubyMemoryControl::print(ostream& out) const
{
}
-void
-RubyMemoryControl::clearStats() const
-{
- m_profiler_ptr->clearStats();
-}
-
-void
-RubyMemoryControl::printStats(ostream& out) const
-{
- m_profiler_ptr->printStats(out);
-}
-
// Queue up a completed request to send back to directory
void
RubyMemoryControl::enqueueToDirectory(MemoryNode req, Cycles latency)
@@ -789,6 +778,12 @@ RubyMemoryControl::functionalWriteBuffers(Packet *pkt)
return num_functional_writes;
}
+void
+RubyMemoryControl::regStats()
+{
+ m_profiler_ptr->regStats();
+}
+
RubyMemoryControl *
RubyMemoryControlParams::create()
{
diff --git a/src/mem/ruby/system/RubyMemoryControl.hh b/src/mem/ruby/system/RubyMemoryControl.hh
index d0dfa5b8d..7be74583a 100644
--- a/src/mem/ruby/system/RubyMemoryControl.hh
+++ b/src/mem/ruby/system/RubyMemoryControl.hh
@@ -81,8 +81,7 @@ class RubyMemoryControl : public MemoryControl
bool areNSlotsAvailable(int n) { return true; }; // infinite queue length
void print(std::ostream& out) const;
- void clearStats() const;
- void printStats(std::ostream& out) const;
+ void regStats();
const int getBank(const physical_address_t addr) const;
const int getRank(const physical_address_t addr) const;
diff --git a/src/mem/slicc/ast/MachineAST.py b/src/mem/slicc/ast/MachineAST.py
index c48d2aef1..d494cb7ce 100644
--- a/src/mem/slicc/ast/MachineAST.py
+++ b/src/mem/slicc/ast/MachineAST.py
@@ -44,10 +44,6 @@ class MachineAST(DeclAST):
s = set(('%s_Controller.cc' % self.ident,
'%s_Controller.hh' % self.ident,
'%s_Controller.py' % self.ident,
- '%s_Profiler.cc' % self.ident,
- '%s_Profiler.hh' % self.ident,
- '%s_ProfileDumper.cc' % self.ident,
- '%s_ProfileDumper.hh' % self.ident,
'%s_Transitions.cc' % self.ident,
'%s_Wakeup.cc' % self.ident))
diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py
index c2ee42553..a110092b6 100644
--- a/src/mem/slicc/symbols/StateMachine.py
+++ b/src/mem/slicc/symbols/StateMachine.py
@@ -173,10 +173,6 @@ class StateMachine(Symbol):
self.printControllerCC(path, includes)
self.printCSwitch(path)
self.printCWakeup(path, includes)
- self.printProfilerCC(path)
- self.printProfilerHH(path)
- self.printProfileDumperCC(path)
- self.printProfileDumperHH(path)
def printControllerPython(self, path):
code = self.symtab.codeFormatter()
@@ -228,8 +224,6 @@ class $py_ident(RubyController):
#include <sstream>
#include <string>
-#include "mem/protocol/${ident}_ProfileDumper.hh"
-#include "mem/protocol/${ident}_Profiler.hh"
#include "mem/protocol/TransitionResult.hh"
#include "mem/protocol/Types.hh"
#include "mem/ruby/common/Consumer.hh"
@@ -263,10 +257,14 @@ class $c_ident : public AbstractController
const std::string toString() const;
const std::string getName() const;
void initNetworkPtr(Network* net_ptr) { m_net_ptr = net_ptr; }
+
void print(std::ostream& out) const;
void wakeup();
void printStats(std::ostream& out) const;
void clearStats();
+ void regStats();
+ void collateStats();
+
void blockOnQueue(Address addr, MessageBuffer* port);
void unblock(Address addr);
void recordCacheTrace(int cntrl, CacheRecorder* tr);
@@ -275,6 +273,12 @@ class $c_ident : public AbstractController
bool functionalReadBuffers(PacketPtr&);
uint32_t functionalWriteBuffers(PacketPtr&);
+ void countTransition(${ident}_State state, ${ident}_Event event);
+ void possibleTransition(${ident}_State state, ${ident}_Event event);
+ uint64 getEventCount(${ident}_Event event);
+ bool isPossible(${ident}_State state, ${ident}_Event event);
+ uint64 getTransitionCount(${ident}_State state, ${ident}_Event event);
+
private:
''')
@@ -319,8 +323,12 @@ TransitionResult doTransitionWorker(${ident}_Event event,
code('''
const Address& addr);
-static ${ident}_ProfileDumper s_profileDumper;
-${ident}_Profiler m_profiler;
+int m_counters[${ident}_State_NUM][${ident}_Event_NUM];
+int m_event_counters[${ident}_Event_NUM];
+bool m_possible[${ident}_State_NUM][${ident}_Event_NUM];
+
+static std::vector<Stats::Vector *> eventVec;
+static std::vector<std::vector<Stats::Vector *> > transVec;
static int m_num_controllers;
// Internal functions
@@ -440,7 +448,8 @@ ${c_ident}Params::create()
}
int $c_ident::m_num_controllers = 0;
-${ident}_ProfileDumper $c_ident::s_profileDumper;
+std::vector<Stats::Vector *> $c_ident::eventVec;
+std::vector<std::vector<Stats::Vector *> > $c_ident::transVec;
// for adding information to the protocol debug trace
stringstream ${ident}_transitionComment;
@@ -520,6 +529,16 @@ m_${{var.c_ident}}_ptr->setSender(this);
code('''
if (p->peer != NULL)
connectWithPeer(p->peer);
+
+for (int state = 0; state < ${ident}_State_NUM; state++) {
+ for (int event = 0; event < ${ident}_Event_NUM; event++) {
+ m_possible[state][event] = false;
+ m_counters[state][event] = 0;
+ }
+}
+for (int event = 0; event < ${ident}_Event_NUM; event++) {
+ m_event_counters[event] = 0;
+}
''')
code.dedent()
code('''
@@ -528,17 +547,13 @@ if (p->peer != NULL)
void
$c_ident::init()
{
- MachineType machine_type;
- int base;
- machine_type = string_to_MachineType("${{var.machine.ident}}");
- base = MachineType_base_number(machine_type);
+ MachineType machine_type = string_to_MachineType("${{var.machine.ident}}");
+ int base = MachineType_base_number(machine_type);
m_machineID.type = MachineType_${ident};
m_machineID.num = m_version;
// initialize objects
- m_profiler.setVersion(m_version);
- s_profileDumper.registerProfiler(&m_profiler);
''')
@@ -675,7 +690,7 @@ $vid->setDescription("[Version " + to_string(m_version) + ", ${ident}, name=${{v
if not stall:
state = "%s_State_%s" % (self.ident, trans.state.ident)
event = "%s_Event_%s" % (self.ident, trans.event.ident)
- code('m_profiler.possibleTransition($state, $event);')
+ code('possibleTransition($state, $event);')
code.dedent()
code('''
@@ -701,6 +716,107 @@ $vid->setDescription("[Version " + to_string(m_version) + ", ${ident}, name=${{v
seq_ident = "m_%s_ptr" % param.name
code('''
+
+void
+$c_ident::regStats()
+{
+ if (m_version == 0) {
+ for (${ident}_Event event = ${ident}_Event_FIRST;
+ event < ${ident}_Event_NUM; ++event) {
+ Stats::Vector *t = new Stats::Vector();
+ t->init(m_num_controllers);
+ t->name(name() + "." + ${ident}_Event_to_string(event));
+ t->flags(Stats::pdf | Stats::total | Stats::oneline |
+ Stats::nozero);
+
+ eventVec.push_back(t);
+ }
+
+ for (${ident}_State state = ${ident}_State_FIRST;
+ state < ${ident}_State_NUM; ++state) {
+
+ transVec.push_back(std::vector<Stats::Vector *>());
+
+ for (${ident}_Event event = ${ident}_Event_FIRST;
+ event < ${ident}_Event_NUM; ++event) {
+
+ Stats::Vector *t = new Stats::Vector();
+ t->init(m_num_controllers);
+ t->name(name() + "." + ${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);
+ }
+ }
+ }
+}
+
+void
+$c_ident::collateStats()
+{
+ for (${ident}_Event event = ${ident}_Event_FIRST;
+ event < ${ident}_Event_NUM; ++event) {
+ for (unsigned int i = 0; i < m_num_controllers; ++i) {
+ std::map<uint32_t, AbstractController *>::iterator it =
+ g_abs_controls[MachineType_${ident}].find(i);
+ assert(it != g_abs_controls[MachineType_${ident}].end());
+ (*eventVec[event])[i] =
+ (($c_ident *)(*it).second)->getEventCount(event);
+ }
+ }
+
+ for (${ident}_State state = ${ident}_State_FIRST;
+ state < ${ident}_State_NUM; ++state) {
+
+ for (${ident}_Event event = ${ident}_Event_FIRST;
+ event < ${ident}_Event_NUM; ++event) {
+
+ for (unsigned int i = 0; i < m_num_controllers; ++i) {
+ std::map<uint32_t, AbstractController *>::iterator it =
+ g_abs_controls[MachineType_${ident}].find(i);
+ assert(it != g_abs_controls[MachineType_${ident}].end());
+ (*transVec[state][event])[i] =
+ (($c_ident *)(*it).second)->getTransitionCount(state, event);
+ }
+ }
+ }
+}
+
+void
+$c_ident::countTransition(${ident}_State state, ${ident}_Event event)
+{
+ assert(m_possible[state][event]);
+ m_counters[state][event]++;
+ m_event_counters[event]++;
+}
+void
+$c_ident::possibleTransition(${ident}_State state,
+ ${ident}_Event event)
+{
+ m_possible[state][event] = true;
+}
+
+uint64
+$c_ident::getEventCount(${ident}_Event event)
+{
+ return m_event_counters[event];
+}
+
+bool
+$c_ident::isPossible(${ident}_State state, ${ident}_Event event)
+{
+ return m_possible[state][event];
+}
+
+uint64
+$c_ident::getTransitionCount(${ident}_State state,
+ ${ident}_Event event)
+{
+ return m_counters[state][event];
+}
+
int
$c_ident::getNumControllers()
{
@@ -768,30 +884,25 @@ $c_ident::printStats(ostream& out) const
# them. Print out these stats before dumping state transition stats.
#
for param in self.config_parameters:
- if param.type_ast.type.ident == "DirectoryMemory" or \
- param.type_ast.type.ident == "MemoryControl":
+ if param.type_ast.type.ident == "DirectoryMemory":
assert(param.pointer)
code(' m_${{param.ident}}_ptr->printStats(out);')
code('''
- if (m_version == 0) {
- s_profileDumper.dumpStats(out);
- }
}
-void $c_ident::clearStats() {
-''')
- #
- # Cache and Memory Controllers have specific profilers associated with
- # them. These stats must be cleared too.
- #
- for param in self.config_parameters:
- if param.type_ast.type.ident == "MemoryControl":
- assert(param.pointer)
- code(' m_${{param.ident}}_ptr->clearStats();')
+void $c_ident::clearStats()
+{
+ for (int state = 0; state < ${ident}_State_NUM; state++) {
+ for (int event = 0; event < ${ident}_Event_NUM; event++) {
+ m_counters[state][event] = 0;
+ }
+ }
+
+ for (int event = 0; event < ${ident}_Event_NUM; event++) {
+ m_event_counters[event] = 0;
+ }
- code('''
- m_profiler.clearStats();
AbstractController::clearStats();
}
''')
@@ -1130,7 +1241,7 @@ ${ident}_Controller::doTransition(${ident}_Event event,
if (result == TransitionResult_Valid) {
DPRINTF(RubyGenerated, "next_state: %s\\n",
${ident}_State_to_string(next_state));
- m_profiler.countTransition(state, event);
+ countTransition(state, event);
DPRINTFR(ProtocolTrace, "%15d %3s %10s%20s %6s>%-6s %s %s\\n",
curTick(), m_version, "${ident}",
${ident}_Event_to_string(event),
@@ -1292,231 +1403,6 @@ if (!checkResourceAvailable(%s_RequestType_%s, addr)) {
''')
code.write(path, "%s_Transitions.cc" % self.ident)
- def printProfileDumperHH(self, path):
- code = self.symtab.codeFormatter()
- ident = self.ident
-
- code('''
-// Auto generated C++ code started by $__file__:$__line__
-// ${ident}: ${{self.short}}
-
-#ifndef __${ident}_PROFILE_DUMPER_HH__
-#define __${ident}_PROFILE_DUMPER_HH__
-
-#include <cassert>
-#include <iostream>
-#include <vector>
-
-#include "${ident}_Event.hh"
-#include "${ident}_Profiler.hh"
-
-typedef std::vector<${ident}_Profiler *> ${ident}_profilers;
-
-class ${ident}_ProfileDumper
-{
- public:
- ${ident}_ProfileDumper();
- void registerProfiler(${ident}_Profiler* profiler);
- void dumpStats(std::ostream& out) const;
-
- private:
- ${ident}_profilers m_profilers;
-};
-
-#endif // __${ident}_PROFILE_DUMPER_HH__
-''')
- code.write(path, "%s_ProfileDumper.hh" % self.ident)
-
- def printProfileDumperCC(self, path):
- code = self.symtab.codeFormatter()
- ident = self.ident
-
- code('''
-// Auto generated C++ code started by $__file__:$__line__
-// ${ident}: ${{self.short}}
-
-#include "mem/protocol/${ident}_ProfileDumper.hh"
-
-${ident}_ProfileDumper::${ident}_ProfileDumper()
-{
-}
-
-void
-${ident}_ProfileDumper::registerProfiler(${ident}_Profiler* profiler)
-{
- if (profiler->getVersion() >= m_profilers.size())
- m_profilers.resize(profiler->getVersion() + 1);
- m_profilers[profiler->getVersion()] = profiler;
-}
-
-void
-${ident}_ProfileDumper::dumpStats(std::ostream& out) const
-{
- out << " --- ${ident} ---\\n";
- out << " - Event Counts -\\n";
- for (${ident}_Event event = ${ident}_Event_FIRST;
- event < ${ident}_Event_NUM;
- ++event) {
- out << (${ident}_Event) event << " [";
- uint64 total = 0;
- for (int i = 0; i < m_profilers.size(); i++) {
- out << m_profilers[i]->getEventCount(event) << " ";
- total += m_profilers[i]->getEventCount(event);
- }
- out << "] " << total << "\\n";
- }
- out << "\\n";
- out << " - Transitions -\\n";
- for (${ident}_State state = ${ident}_State_FIRST;
- state < ${ident}_State_NUM;
- ++state) {
- for (${ident}_Event event = ${ident}_Event_FIRST;
- event < ${ident}_Event_NUM;
- ++event) {
- if (m_profilers[0]->isPossible(state, event)) {
- out << (${ident}_State) state << " "
- << (${ident}_Event) event << " [";
- uint64 total = 0;
- for (int i = 0; i < m_profilers.size(); i++) {
- out << m_profilers[i]->getTransitionCount(state, event) << " ";
- total += m_profilers[i]->getTransitionCount(state, event);
- }
- out << "] " << total << "\\n";
- }
- }
- out << "\\n";
- }
-}
-''')
- code.write(path, "%s_ProfileDumper.cc" % self.ident)
-
- def printProfilerHH(self, path):
- code = self.symtab.codeFormatter()
- ident = self.ident
-
- code('''
-// Auto generated C++ code started by $__file__:$__line__
-// ${ident}: ${{self.short}}
-
-#ifndef __${ident}_PROFILER_HH__
-#define __${ident}_PROFILER_HH__
-
-#include <cassert>
-#include <iostream>
-
-#include "mem/protocol/${ident}_Event.hh"
-#include "mem/protocol/${ident}_State.hh"
-#include "mem/ruby/common/TypeDefines.hh"
-
-class ${ident}_Profiler
-{
- public:
- ${ident}_Profiler();
- void setVersion(int version);
- int getVersion();
- void countTransition(${ident}_State state, ${ident}_Event event);
- void possibleTransition(${ident}_State state, ${ident}_Event event);
- uint64 getEventCount(${ident}_Event event);
- bool isPossible(${ident}_State state, ${ident}_Event event);
- uint64 getTransitionCount(${ident}_State state, ${ident}_Event event);
- void clearStats();
-
- private:
- int m_counters[${ident}_State_NUM][${ident}_Event_NUM];
- int m_event_counters[${ident}_Event_NUM];
- bool m_possible[${ident}_State_NUM][${ident}_Event_NUM];
- int m_version;
-};
-
-#endif // __${ident}_PROFILER_HH__
-''')
- code.write(path, "%s_Profiler.hh" % self.ident)
-
- def printProfilerCC(self, path):
- code = self.symtab.codeFormatter()
- ident = self.ident
-
- code('''
-// Auto generated C++ code started by $__file__:$__line__
-// ${ident}: ${{self.short}}
-
-#include <cassert>
-
-#include "mem/protocol/${ident}_Profiler.hh"
-
-${ident}_Profiler::${ident}_Profiler()
-{
- for (int state = 0; state < ${ident}_State_NUM; state++) {
- for (int event = 0; event < ${ident}_Event_NUM; event++) {
- m_possible[state][event] = false;
- m_counters[state][event] = 0;
- }
- }
- for (int event = 0; event < ${ident}_Event_NUM; event++) {
- m_event_counters[event] = 0;
- }
-}
-
-void
-${ident}_Profiler::setVersion(int version)
-{
- m_version = version;
-}
-
-int
-${ident}_Profiler::getVersion()
-{
- return m_version;
-}
-
-void
-${ident}_Profiler::clearStats()
-{
- for (int state = 0; state < ${ident}_State_NUM; state++) {
- for (int event = 0; event < ${ident}_Event_NUM; event++) {
- m_counters[state][event] = 0;
- }
- }
-
- for (int event = 0; event < ${ident}_Event_NUM; event++) {
- m_event_counters[event] = 0;
- }
-}
-void
-${ident}_Profiler::countTransition(${ident}_State state, ${ident}_Event event)
-{
- assert(m_possible[state][event]);
- m_counters[state][event]++;
- m_event_counters[event]++;
-}
-void
-${ident}_Profiler::possibleTransition(${ident}_State state,
- ${ident}_Event event)
-{
- m_possible[state][event] = true;
-}
-
-uint64
-${ident}_Profiler::getEventCount(${ident}_Event event)
-{
- return m_event_counters[event];
-}
-
-bool
-${ident}_Profiler::isPossible(${ident}_State state, ${ident}_Event event)
-{
- return m_possible[state][event];
-}
-
-uint64
-${ident}_Profiler::getTransitionCount(${ident}_State state,
- ${ident}_Event event)
-{
- return m_counters[state][event];
-}
-
-''')
- code.write(path, "%s_Profiler.cc" % self.ident)
# **************************
# ******* HTML Files *******