summaryrefslogtreecommitdiff
path: root/src/mem/ruby/profiler
diff options
context:
space:
mode:
authorNilay Vaish <nilay@cs.wisc.edu>2013-06-09 07:29:59 -0500
committerNilay Vaish <nilay@cs.wisc.edu>2013-06-09 07:29:59 -0500
commitf59a7af50a7309944abfe1997057f52591619635 (patch)
tree4daa578b6ba1664152da4412786317bce26ff0ee /src/mem/ruby/profiler
parent38736ce7c33d7b1bf1e982f5d8cacd13908a32f4 (diff)
downloadgem5-f59a7af50a7309944abfe1997057f52591619635.tar.xz
ruby: stats: use gem5's stats for cache and memory controllers
This moves event and transition count statistics for cache controllers to gem5's statistics. It does the same for the statistics associated with the memory controller in ruby. All the cache/directory/dma controllers individually collect the event and transition counts. A callback function, collateStats(), has been added that is invoked on the controller version 0 of each controller class. This function adds all the individual controller statistics to a vector variables. All the code for registering the statistical variables and collating them is generated by SLICC. The patch removes the files *_Profiler.{cc,hh} and *_ProfileDumper.{cc,hh} which were earlier used for collecting and dumping statistics respectively.
Diffstat (limited to 'src/mem/ruby/profiler')
-rw-r--r--src/mem/ruby/profiler/MemCntrlProfiler.cc215
-rw-r--r--src/mem/ruby/profiler/MemCntrlProfiler.hh41
2 files changed, 152 insertions, 104 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;