I feel like a just reviewed a patch that affected a lot of the same stuff. Should you just fold the two? At the very least, it seems to me that there should be some re-factoring.
Nate On Mon, Dec 21, 2009 at 8:43 AM, Brad Beckmann <[email protected]> wrote: > # HG changeset patch > # User Brad Beckmann <[email protected]> > # Date 1261412980 28800 > # Node ID e1df8da6de6ac36ddcb421d7d88917c2d01d13db > # Parent 6171341ed54d519d97d1430049238e16d9e5d676 > ruby: cleaned up ruby profilers > Cleaned up the ruby profilers by moving the memory controller profiling code > out of the main profiler object and into a separate object similar to the > current CacheProfiler. Both the CacheProfiler and MemCntrlProfiler are > specific to a particular Ruby object, CacheMemory and MemoryControl > respectively. Therefore, these profilers should not be SimObjects and > created by the python configuration system, but instead private objects. This > simplifies the creation of these profilers. > > diff -r 6171341ed54d -r e1df8da6de6a configs/ruby/MOESI_hammer.py > --- a/configs/ruby/MOESI_hammer.py Mon Dec 21 08:29:40 2009 -0800 > +++ b/configs/ruby/MOESI_hammer.py Mon Dec 21 08:29:40 2009 -0800 > @@ -67,14 +67,9 @@ > # > # First create the Ruby objects associated with this cpu > # > - l1i_profiler = CacheProfiler(description = ("l1i_%s_profiler" % i)) > - l1i_cache = L1Cache(cache_profiler = l1i_profiler) > - > - l1d_profiler = CacheProfiler(description = ("l1d_%s_profiler" % i)) > - l1d_cache = L1Cache(cache_profiler = l1d_profiler) > - > - l2_profiler = CacheProfiler(description = ("l2_%s_profiler" % i)) > - l2_cache = L2Cache(cache_profiler = l2_profiler) > + l1i_cache = L1Cache() > + l1d_cache = L1Cache() > + l2_cache = L2Cache() > > cpu_seq = RubySequencer(icache = l1i_cache, > dcache = l1d_cache, > diff -r 6171341ed54d -r e1df8da6de6a configs/ruby/Ruby.py > --- a/configs/ruby/Ruby.py Mon Dec 21 08:29:40 2009 -0800 > +++ b/configs/ruby/Ruby.py Mon Dec 21 08:29:40 2009 -0800 > @@ -57,20 +57,7 @@ > mem_size_mb = sum([int(dir_cntrl.directory.size_mb) \ > for dir_cntrl in dir_cntrls]) > > - # > - # determine the number of memory controllers and other memory controller > - # parameters for the profiler > - # > - mcCount = len(dir_cntrls) > - banksPerRank = dir_cntrls[0].memBuffer.banks_per_rank > - ranksPerDimm = dir_cntrls[0].memBuffer.ranks_per_dimm > - dimmsPerChannel = dir_cntrls[0].memBuffer.dimms_per_channel > - > - ruby_profiler = RubyProfiler(num_of_sequencers = len(cpu_sequencers), > - mem_cntrl_count = mcCount, > - banks_per_rank = banksPerRank, > - ranks_per_dimm = ranksPerDimm, > - dimms_per_channel = dimmsPerChannel) > + ruby_profiler = RubyProfiler(num_of_sequencers = len(cpu_sequencers)) > > ruby = RubySystem(clock = options.clock, > network = network, > diff -r 6171341ed54d -r e1df8da6de6a src/mem/ruby/profiler/CacheProfiler.cc > --- a/src/mem/ruby/profiler/CacheProfiler.cc Mon Dec 21 08:29:40 2009 -0800 > +++ b/src/mem/ruby/profiler/CacheProfiler.cc Mon Dec 21 08:29:40 2009 -0800 > @@ -43,10 +43,9 @@ > #include "mem/ruby/profiler/Profiler.hh" > #include "mem/gems_common/Vector.hh" > > -CacheProfiler::CacheProfiler(const CacheProfilerParams* params) > - : SimObject(params), m_requestSize(-1) > +CacheProfiler::CacheProfiler(const string& description) > { > - m_description = params->description; > + m_description = description; > m_requestTypeVec_ptr = new Vector<int>; > m_requestTypeVec_ptr->setSize(int(CacheRequestType_NUM)); > > @@ -60,7 +59,7 @@ > > void CacheProfiler::printStats(ostream& out) const > { > - out << m_description << " cache stats: " << endl; > + out << "Cache Stats: " << m_description << endl; > string description = " " + m_description; > > out << description << "_total_misses: " << m_misses << endl; > @@ -140,9 +139,3 @@ > m_hw_prefetches++; > } > } > - > -CacheProfiler * > -CacheProfilerParams::create() > -{ > - return new CacheProfiler(this); > -} > diff -r 6171341ed54d -r e1df8da6de6a src/mem/ruby/profiler/CacheProfiler.hh > --- a/src/mem/ruby/profiler/CacheProfiler.hh Mon Dec 21 08:29:40 2009 -0800 > +++ b/src/mem/ruby/profiler/CacheProfiler.hh Mon Dec 21 08:29:40 2009 -0800 > @@ -46,15 +46,12 @@ > #include "mem/protocol/PrefetchBit.hh" > #include "mem/protocol/CacheRequestType.hh" > > -#include "params/CacheProfiler.hh" > - > template <class TYPE> class Vector; > > -class CacheProfiler : public SimObject { > +class CacheProfiler { > public: > // Constructors > - typedef CacheProfilerParams Params; > - CacheProfiler(const Params *); > + CacheProfiler(const string& description); > > // Destructor > ~CacheProfiler(); > diff -r 6171341ed54d -r e1df8da6de6a src/mem/ruby/profiler/MemCntrlProfiler.cc > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/src/mem/ruby/profiler/MemCntrlProfiler.cc Mon Dec 21 08:29:40 2009 -0800 > @@ -0,0 +1,184 @@ > + > +/* > + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > + * met: redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer; > + * redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution; > + * neither the name of the copyright holders nor the names of its > + * contributors may be used to endorse or promote products derived from > + * this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT > + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR > + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT > + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, > + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT > + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE > + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include "mem/ruby/profiler/MemCntrlProfiler.hh" > + > +MemCntrlProfiler::MemCntrlProfiler(const string& description, > + int banks_per_rank, > + int ranks_per_dimm, > + int dimms_per_channel) > +{ > + m_description = 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.setSize(totalBanks); > + > + clearStats(); > +} > + > +MemCntrlProfiler::~MemCntrlProfiler() > +{ > +} > + > +void MemCntrlProfiler::printStats(ostream& out) const > +{ > + if (m_memReq || m_memRefresh) { // 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; > + out << " memory_total_requests: " << m_memReq << endl; // does not > include refreshes > + 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] << " "; > + } > + } else { > + out << "Memory Controller: " << m_description > + << " no stats recorded." << endl; > + } > + 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++; > + m_memBankCount[bank]++; > +} > + > +void MemCntrlProfiler::profileMemBankBusy() { > + m_memBankBusy++; > +} > + > +void MemCntrlProfiler::profileMemBusBusy() { > + m_memBusBusy++; > +} > + > +void MemCntrlProfiler::profileMemReadWriteBusy() { > + m_memReadWriteBusy++; > +} > + > +void MemCntrlProfiler::profileMemDataBusBusy() { > + m_memDataBusBusy++; > +} > + > +void MemCntrlProfiler::profileMemTfawBusy() { > + m_memTfawBusy++; > +} > + > +void MemCntrlProfiler::profileMemRefresh() { > + m_memRefresh++; > +} > + > +void MemCntrlProfiler::profileMemRead() { > + m_memRead++; > +} > + > +void MemCntrlProfiler::profileMemWrite() { > + m_memWrite++; > +} > + > +void MemCntrlProfiler::profileMemWaitCycles(int cycles) { > + m_memWaitCycles += cycles; > +} > + > +void MemCntrlProfiler::profileMemInputQ(int cycles) { > + m_memInputQ += cycles; > +} > + > +void MemCntrlProfiler::profileMemBankQ(int cycles) { > + m_memBankQ += cycles; > +} > + > +void MemCntrlProfiler::profileMemArbWait(int cycles) { > + m_memArbWait += cycles; > +} > + > +void MemCntrlProfiler::profileMemRandBusy() { > + m_memRandBusy++; > +} > + > +void MemCntrlProfiler::profileMemNotOld() { > + m_memNotOld++; > +} > + > + > diff -r 6171341ed54d -r e1df8da6de6a src/mem/ruby/profiler/MemCntrlProfiler.hh > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/src/mem/ruby/profiler/MemCntrlProfiler.hh Mon Dec 21 08:29:40 2009 -0800 > @@ -0,0 +1,123 @@ > + > +/* > + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > + * met: redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer; > + * redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution; > + * neither the name of the copyright holders nor the names of its > + * contributors may be used to endorse or promote products derived from > + * this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT > + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR > + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT > + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, > + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT > + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE > + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +/* > + * MemCntrlProfiler.hh > + * > + * Description: > + * > + * $Id$ > + * > + */ > + > +#ifndef MEM_CNTRL_PROFILER_H > +#define MEM_CNTRL_PROFILER_H > + > +#include "mem/gems_common/Vector.hh" > +#include "mem/ruby/common/Global.hh" > + > +template <class TYPE> class Vector; > + > +class MemCntrlProfiler { > +public: > + // Constructors > + MemCntrlProfiler(const string& description, > + int banks_per_rank, > + int ranks_per_dimm, > + int dimms_per_channel); > + > + // Destructor > + ~MemCntrlProfiler(); > + > + // Public Methods > + void printStats(ostream& out) const; > + void clearStats(); > + > + void profileMemReq(int bank); > + void profileMemBankBusy(); > + void profileMemBusBusy(); > + void profileMemTfawBusy(); > + void profileMemReadWriteBusy(); > + void profileMemDataBusBusy(); > + void profileMemRefresh(); > + void profileMemRead(); > + void profileMemWrite(); > + void profileMemWaitCycles(int cycles); > + void profileMemInputQ(int cycles); > + void profileMemBankQ(int cycles); > + void profileMemArbWait(int cycles); > + void profileMemRandBusy(); > + void profileMemNotOld(); > + > + void print(ostream& out) const; > +private: > + // Private Methods > + > + // Private copy constructor and assignment operator > + MemCntrlProfiler(const MemCntrlProfiler& obj); > + MemCntrlProfiler& operator=(const MemCntrlProfiler& obj); > + > + // Data Members (m_ prefix) > + 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; > + Vector<uint64> m_memBankCount; > + int m_banks_per_rank; > + int m_ranks_per_dimm; > + int m_dimms_per_channel; > +}; > + > +// Output operator declaration > +ostream& operator<<(ostream& out, const MemCntrlProfiler& obj); > + > +// ******************* Definitions ******************* > + > +// Output operator definition > +extern inline > +ostream& operator<<(ostream& out, const MemCntrlProfiler& obj) > +{ > + obj.print(out); > + out << flush; > + return out; > +} > + > +#endif //MEM_CNTRL_PROFILER_H > diff -r 6171341ed54d -r e1df8da6de6a src/mem/ruby/profiler/Profiler.cc > --- a/src/mem/ruby/profiler/Profiler.cc Mon Dec 21 08:29:40 2009 -0800 > +++ b/src/mem/ruby/profiler/Profiler.cc Mon Dec 21 08:29:40 2009 -0800 > @@ -90,40 +90,6 @@ > > m_num_of_sequencers = p->num_of_sequencers; > > - // > - // Initialize the memory controller profiler structs > - // > - m_mc_profilers.setSize(p->mem_cntrl_count); > - for (int mem_cntrl = 0; mem_cntrl < p->mem_cntrl_count; mem_cntrl++) { > - m_mc_profilers[mem_cntrl] = new memory_control_profiler; > - m_mc_profilers[mem_cntrl]->m_memReq = 0; > - m_mc_profilers[mem_cntrl]->m_memBankBusy = 0; > - m_mc_profilers[mem_cntrl]->m_memBusBusy = 0; > - m_mc_profilers[mem_cntrl]->m_memReadWriteBusy = 0; > - m_mc_profilers[mem_cntrl]->m_memDataBusBusy = 0; > - m_mc_profilers[mem_cntrl]->m_memTfawBusy = 0; > - m_mc_profilers[mem_cntrl]->m_memRefresh = 0; > - m_mc_profilers[mem_cntrl]->m_memRead = 0; > - m_mc_profilers[mem_cntrl]->m_memWrite = 0; > - m_mc_profilers[mem_cntrl]->m_memWaitCycles = 0; > - m_mc_profilers[mem_cntrl]->m_memInputQ = 0; > - m_mc_profilers[mem_cntrl]->m_memBankQ = 0; > - m_mc_profilers[mem_cntrl]->m_memArbWait = 0; > - m_mc_profilers[mem_cntrl]->m_memRandBusy = 0; > - m_mc_profilers[mem_cntrl]->m_memNotOld = 0; > - > - m_mc_profilers[mem_cntrl]->m_banks_per_rank = p->banks_per_rank; > - m_mc_profilers[mem_cntrl]->m_ranks_per_dimm = p->ranks_per_dimm; > - m_mc_profilers[mem_cntrl]->m_dimms_per_channel = > - p->dimms_per_channel; > - > - int totalBanks = p->banks_per_rank * > - p->ranks_per_dimm * > - p->dimms_per_channel; > - > - m_mc_profilers[mem_cntrl]->m_memBankCount.setSize(totalBanks); > - } > - > m_hot_lines = false; > m_all_instructions = false; > > @@ -144,12 +110,6 @@ > delete m_periodic_output_file_ptr; > } > > - for (int mem_cntrl = 0; > - mem_cntrl < m_mc_profilers.size(); > - mem_cntrl++) { > - delete m_mc_profilers[mem_cntrl]; > - } > - > delete m_requestProfileMap_ptr; > } > > @@ -363,64 +323,6 @@ > > out << endl; > > - for (int mem_cntrl = 0; > - mem_cntrl < m_mc_profilers.size(); > - mem_cntrl++) { > - uint64 m_memReq = m_mc_profilers[mem_cntrl]->m_memReq; > - uint64 m_memRefresh = m_mc_profilers[mem_cntrl]->m_memRefresh; > - uint64 m_memInputQ = m_mc_profilers[mem_cntrl]->m_memInputQ; > - uint64 m_memBankQ = m_mc_profilers[mem_cntrl]->m_memBankQ; > - uint64 m_memWaitCycles = m_mc_profilers[mem_cntrl]->m_memWaitCycles; > - uint64 m_memRead = m_mc_profilers[mem_cntrl]->m_memRead; > - uint64 m_memWrite = m_mc_profilers[mem_cntrl]->m_memWrite; > - uint64 m_memBankBusy = m_mc_profilers[mem_cntrl]->m_memBankBusy; > - uint64 m_memRandBusy = m_mc_profilers[mem_cntrl]->m_memRandBusy; > - uint64 m_memNotOld = m_mc_profilers[mem_cntrl]->m_memNotOld; > - uint64 m_memArbWait = m_mc_profilers[mem_cntrl]->m_memArbWait; > - uint64 m_memBusBusy = m_mc_profilers[mem_cntrl]->m_memBusBusy; > - uint64 m_memTfawBusy = m_mc_profilers[mem_cntrl]->m_memTfawBusy; > - uint64 m_memReadWriteBusy = > m_mc_profilers[mem_cntrl]->m_memReadWriteBusy; > - uint64 m_memDataBusBusy = m_mc_profilers[mem_cntrl]->m_memDataBusBusy; > - Vector<uint64> m_memBankCount = > m_mc_profilers[mem_cntrl]->m_memBankCount; > - > - if (m_memReq || m_memRefresh) { // 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 control " << mem_cntrl << ":" << endl; > - out << " memory_total_requests: " << m_memReq << endl; // does not > include refreshes > - 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] << " "; > - //if ((bank % 8) == 7) out << " " << endl; > - } > - out << endl; > - out << endl; > - } > - } > if (!short_stats) { > out << "Busy Controller Counts:" << endl; > for(int i=0; i < MachineType_NUM; i++) { > @@ -643,34 +545,6 @@ > m_outstanding_requests.clear(); > m_outstanding_persistent_requests.clear(); > > -//added by SS > - vector<string>::iterator it; > - > - for (int mem_cntrl = 0; > - mem_cntrl < m_mc_profilers.size(); > - mem_cntrl++) { > - m_mc_profilers[mem_cntrl]->m_memReq = 0; > - m_mc_profilers[mem_cntrl]->m_memBankBusy = 0; > - m_mc_profilers[mem_cntrl]->m_memBusBusy = 0; > - m_mc_profilers[mem_cntrl]->m_memTfawBusy = 0; > - m_mc_profilers[mem_cntrl]->m_memReadWriteBusy = 0; > - m_mc_profilers[mem_cntrl]->m_memDataBusBusy = 0; > - m_mc_profilers[mem_cntrl]->m_memRefresh = 0; > - m_mc_profilers[mem_cntrl]->m_memRead = 0; > - m_mc_profilers[mem_cntrl]->m_memWrite = 0; > - m_mc_profilers[mem_cntrl]->m_memWaitCycles = 0; > - m_mc_profilers[mem_cntrl]->m_memInputQ = 0; > - m_mc_profilers[mem_cntrl]->m_memBankQ = 0; > - m_mc_profilers[mem_cntrl]->m_memArbWait = 0; > - m_mc_profilers[mem_cntrl]->m_memRandBusy = 0; > - m_mc_profilers[mem_cntrl]->m_memNotOld = 0; > - > - for (int bank=0; > - bank < m_mc_profilers[mem_cntrl]->m_memBankCount.size(); > - bank++) { > - m_mc_profilers[mem_cntrl]->m_memBankCount[bank] = 0; > - } > - } > // Flush the prefetches through the system - used so that there are no > outstanding requests after stats are cleared > //g_eventQueue_ptr->triggerAllEvents(); > > @@ -863,68 +737,6 @@ > return m_perProcEndTransaction.sum(); > } > > -// For MemoryControl: > -void Profiler::profileMemReq(int mem_cntrl, int bank) { > - m_mc_profilers[mem_cntrl]->m_memReq++; > - m_mc_profilers[mem_cntrl]->m_memBankCount[bank]++; > -} > - > -void Profiler::profileMemBankBusy(int mem_cntrl) { > - m_mc_profilers[mem_cntrl]->m_memBankBusy++; > -} > - > -void Profiler::profileMemBusBusy(int mem_cntrl) { > - m_mc_profilers[mem_cntrl]->m_memBusBusy++; > -} > - > -void Profiler::profileMemReadWriteBusy(int mem_cntrl) { > - m_mc_profilers[mem_cntrl]->m_memReadWriteBusy++; > -} > - > -void Profiler::profileMemDataBusBusy(int mem_cntrl) { > - m_mc_profilers[mem_cntrl]->m_memDataBusBusy++; > -} > - > -void Profiler::profileMemTfawBusy(int mem_cntrl) { > - m_mc_profilers[mem_cntrl]->m_memTfawBusy++; > -} > - > -void Profiler::profileMemRefresh(int mem_cntrl) { > - m_mc_profilers[mem_cntrl]->m_memRefresh++; > -} > - > -void Profiler::profileMemRead(int mem_cntrl) { > - m_mc_profilers[mem_cntrl]->m_memRead++; > -} > - > -void Profiler::profileMemWrite(int mem_cntrl) { > - m_mc_profilers[mem_cntrl]->m_memWrite++; > -} > - > -void Profiler::profileMemWaitCycles(int mem_cntrl, int cycles) { > - m_mc_profilers[mem_cntrl]->m_memWaitCycles += cycles; > -} > - > -void Profiler::profileMemInputQ(int mem_cntrl, int cycles) { > - m_mc_profilers[mem_cntrl]->m_memInputQ += cycles; > -} > - > -void Profiler::profileMemBankQ(int mem_cntrl, int cycles) { > - m_mc_profilers[mem_cntrl]->m_memBankQ += cycles; > -} > - > -void Profiler::profileMemArbWait(int mem_cntrl, int cycles) { > - m_mc_profilers[mem_cntrl]->m_memArbWait += cycles; > -} > - > -void Profiler::profileMemRandBusy(int mem_cntrl) { > - m_mc_profilers[mem_cntrl]->m_memRandBusy++; > -} > - > -void Profiler::profileMemNotOld(int mem_cntrl) { > - m_mc_profilers[mem_cntrl]->m_memNotOld++; > -} > - > > Profiler * > RubyProfilerParams::create() > diff -r 6171341ed54d -r e1df8da6de6a src/mem/ruby/profiler/Profiler.hh > --- a/src/mem/ruby/profiler/Profiler.hh Mon Dec 21 08:29:40 2009 -0800 > +++ b/src/mem/ruby/profiler/Profiler.hh Mon Dec 21 08:29:40 2009 -0800 > @@ -79,29 +79,6 @@ > > template <class KEY_TYPE, class VALUE_TYPE> class Map; > > -struct memory_control_profiler { > - 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; > - Vector<uint64> m_memBankCount; > - int m_banks_per_rank; > - int m_ranks_per_dimm; > - int m_dimms_per_channel; > -}; > - > - > class Profiler : public SimObject, public Consumer { > public: > // Constructors > @@ -170,29 +147,11 @@ > return m_ruby_start; > } > > - // added for MemoryControl: > - void profileMemReq(int mem_cntrl, int bank); > - void profileMemBankBusy(int mem_cntrl); > - void profileMemBusBusy(int mem_cntrl); > - void profileMemTfawBusy(int mem_cntrl); > - void profileMemReadWriteBusy(int mem_cntrl); > - void profileMemDataBusBusy(int mem_cntrl); > - void profileMemRefresh(int mem_cntrl); > - void profileMemRead(int mem_cntrl); > - void profileMemWrite(int mem_cntrl); > - void profileMemWaitCycles(int mem_cntrl, int cycles); > - void profileMemInputQ(int mem_cntrl, int cycles); > - void profileMemBankQ(int mem_cntrl, int cycles); > - void profileMemArbWait(int mem_cntrl, int cycles); > - void profileMemRandBusy(int mem_cntrl); > - void profileMemNotOld(int mem_cntrl); > //added by SS > bool getHotLines() { return m_hot_lines; } > bool getAllInstructions() { return m_all_instructions; } > > private: > - //added by SS > - vector<string> m_memory_control_names; > > // Private copy constructor and assignment operator > Profiler(const Profiler& obj); > @@ -255,10 +214,6 @@ > int m_requests; > Map <string, int>* m_requestProfileMap_ptr; > > - // added for MemoryControl: > - //added by SS > - Vector < memory_control_profiler* > m_mc_profilers; > - > //added by SS > bool m_hot_lines; > bool m_all_instructions; > diff -r 6171341ed54d -r e1df8da6de6a src/mem/ruby/profiler/Profiler.py > --- a/src/mem/ruby/profiler/Profiler.py Mon Dec 21 08:29:40 2009 -0800 > +++ b/src/mem/ruby/profiler/Profiler.py Mon Dec 21 08:29:40 2009 -0800 > @@ -7,12 +7,3 @@ > hot_lines = Param.Bool(False, "") > all_instructions = Param.Bool(False, "") > num_of_sequencers = Param.Int("") > - mem_cntrl_count = Param.Int(0, "") > - banks_per_rank = Param.Int("") > - ranks_per_dimm = Param.Int("") > - dimms_per_channel = Param.Int("") > - > -class CacheProfiler(SimObject): > - type = 'CacheProfiler' > - cxx_class = 'CacheProfiler' > - description = Param.String("") > diff -r 6171341ed54d -r e1df8da6de6a src/mem/ruby/profiler/SConscript > --- a/src/mem/ruby/profiler/SConscript Mon Dec 21 08:29:40 2009 -0800 > +++ b/src/mem/ruby/profiler/SConscript Mon Dec 21 08:29:40 2009 -0800 > @@ -38,5 +38,6 @@ > Source('AccessTraceForAddress.cc') > Source('AddressProfiler.cc') > Source('CacheProfiler.cc') > +Source('MemCntrlProfiler.cc') > Source('Profiler.cc') > Source('StoreTrace.cc') > diff -r 6171341ed54d -r e1df8da6de6a src/mem/ruby/system/Cache.py > --- a/src/mem/ruby/system/Cache.py Mon Dec 21 08:29:40 2009 -0800 > +++ b/src/mem/ruby/system/Cache.py Mon Dec 21 08:29:40 2009 -0800 > @@ -9,4 +9,3 @@ > latency = Param.Int(""); > assoc = Param.Int(""); > replacement_policy = Param.String("PSEUDO_LRU", ""); > - cache_profiler = Param.CacheProfiler(""); > diff -r 6171341ed54d -r e1df8da6de6a src/mem/ruby/system/CacheMemory.cc > --- a/src/mem/ruby/system/CacheMemory.cc Mon Dec 21 08:29:40 2009 -0800 > +++ b/src/mem/ruby/system/CacheMemory.cc Mon Dec 21 08:29:40 2009 -0800 > @@ -58,7 +58,7 @@ > m_latency = p->latency; > m_cache_assoc = p->assoc; > m_policy = p->replacement_policy; > - m_profiler_ptr = p->cache_profiler; > + m_profiler_ptr = new CacheProfiler(name()); > } > > > diff -r 6171341ed54d -r e1df8da6de6a src/mem/ruby/system/MemoryControl.cc > --- a/src/mem/ruby/system/MemoryControl.cc Mon Dec 21 08:29:40 2009 -0800 > +++ b/src/mem/ruby/system/MemoryControl.cc Mon Dec 21 08:29:40 2009 -0800 > @@ -154,7 +154,6 @@ > MemoryControl::MemoryControl(const Params *p) > : SimObject(p) > { > - m_version = p->version; > m_mem_bus_cycle_multiplier = p->mem_bus_cycle_multiplier; > m_banks_per_rank = p->banks_per_rank; > m_ranks_per_dimm = p->ranks_per_dimm; > @@ -172,6 +171,11 @@ > m_tFaw = p->tFaw; > m_mem_random_arbitrate = p->mem_random_arbitrate; > m_mem_fixed_delay = p->mem_fixed_delay; > + > + m_profiler_ptr = new MemCntrlProfiler(name(), > + m_banks_per_rank, > + m_ranks_per_dimm, > + m_dimms_per_channel); > } > > void MemoryControl::init() > @@ -179,8 +183,6 @@ > m_msg_counter = 0; > > m_debug = 0; > - //if (m_version == 0) m_debug = 1; > - > > assert(m_tFaw <= 62); // must fit in a uint64 shift register > > @@ -235,6 +237,7 @@ > delete [] m_bankQueues; > delete [] m_bankBusyCounter; > delete [] m_oldRequest; > + delete m_profiler_ptr; > } > > > @@ -268,7 +271,7 @@ > printf("bank =%3x\n", bank); > } > > - g_system_ptr->getProfiler()->profileMemReq(m_version, bank); > + m_profiler_ptr->profileMemReq(bank); > m_input_queue.push_back(memRef); > if (!m_awakened) { > g_eventQueue_ptr->scheduleEvent(this, 1); > @@ -321,7 +324,7 @@ > > > void MemoryControl::printConfig (ostream& out) { > - // out << "Memory Control " << m_version << ":" << endl; > + out << "Memory Control " << name() << ":" << endl; > out << " Ruby cycles per memory cycle: " << m_mem_bus_cycle_multiplier << > endl; > out << " Basic read latency: " << m_mem_ctl_latency << endl; > if (m_mem_fixed_delay) { > @@ -349,6 +352,16 @@ > m_debug = debugFlag; > } > > +void MemoryControl::clearStats() const > +{ > + m_profiler_ptr->clearStats(); > +} > + > +void MemoryControl::printStats(ostream& out) const > +{ > + m_profiler_ptr->printStats(out); > +} > + > > // **************************************************************** > > @@ -395,19 +408,19 @@ > > bool MemoryControl::queueReady (int bank) { > if ((m_bankBusyCounter[bank] > 0) && !m_mem_fixed_delay) { > - g_system_ptr->getProfiler()->profileMemBankBusy(m_version); > + m_profiler_ptr->profileMemBankBusy(); > //if (m_debug) printf(" bank %x busy %d\n", bank, > m_bankBusyCounter[bank]); > return false; > } > if (m_mem_random_arbitrate >= 2) { > if ((random() % 100) < m_mem_random_arbitrate) { > - g_system_ptr->getProfiler()->profileMemRandBusy(m_version); > + m_profiler_ptr->profileMemRandBusy(); > return false; > } > } > if (m_mem_fixed_delay) return true; > if ((m_ageCounter > (2 * m_bank_busy_time)) && !m_oldRequest[bank]) { > - g_system_ptr->getProfiler()->profileMemNotOld(m_version); > + m_profiler_ptr->profileMemNotOld(); > return false; > } > if (m_busBusyCounter_Basic == m_basic_bus_busy_time) { > @@ -416,26 +429,26 @@ > // a bus wait. This is a little inaccurate since it MIGHT > // have also been blocked waiting for a read-write or a > // read-read instead, but it's pretty close. > - g_system_ptr->getProfiler()->profileMemArbWait(m_version, 1); > + m_profiler_ptr->profileMemArbWait(1); > return false; > } > if (m_busBusyCounter_Basic > 0) { > - g_system_ptr->getProfiler()->profileMemBusBusy(m_version); > + m_profiler_ptr->profileMemBusBusy(); > return false; > } > int rank = getRank(bank); > if (m_tfaw_count[rank] >= ACTIVATE_PER_TFAW) { > - g_system_ptr->getProfiler()->profileMemTfawBusy(m_version); > + m_profiler_ptr->profileMemTfawBusy(); > return false; > } > bool write = !m_bankQueues[bank].front().m_is_mem_read; > if (write && (m_busBusyCounter_Write > 0)) { > - g_system_ptr->getProfiler()->profileMemReadWriteBusy(m_version); > + m_profiler_ptr->profileMemReadWriteBusy(); > return false; > } > if (!write && (rank != m_busBusy_WhichRank) > && (m_busBusyCounter_ReadNewRank > 0)) { > - g_system_ptr->getProfiler()->profileMemDataBusBusy(m_version); > + m_profiler_ptr->profileMemDataBusBusy(); > return false; > } > return true; > @@ -460,7 +473,7 @@ > //uint64 current_time = g_eventQueue_ptr->getTime(); > //printf(" Refresh bank %3x at %lld\n", bank, current_time); > //} > - g_system_ptr->getProfiler()->profileMemRefresh(m_version); > + m_profiler_ptr->profileMemRefresh(); > m_need_refresh--; > m_refresh_bank++; > if (m_refresh_bank >= m_total_banks) m_refresh_bank = 0; > @@ -504,12 +517,12 @@ > m_bankBusyCounter[bank] = m_bank_busy_time; > m_busBusy_WhichRank = rank; > if (req.m_is_mem_read) { > - g_system_ptr->getProfiler()->profileMemRead(m_version); > + m_profiler_ptr->profileMemRead(); > m_busBusyCounter_Basic = m_basic_bus_busy_time; > m_busBusyCounter_Write = m_basic_bus_busy_time + m_read_write_delay; > m_busBusyCounter_ReadNewRank = m_basic_bus_busy_time + m_rank_rank_delay; > } else { > - g_system_ptr->getProfiler()->profileMemWrite(m_version); > + m_profiler_ptr->profileMemWrite(); > m_busBusyCounter_Basic = m_basic_bus_busy_time; > m_busBusyCounter_Write = m_basic_bus_busy_time; > m_busBusyCounter_ReadNewRank = m_basic_bus_busy_time; > @@ -578,7 +591,7 @@ > issueRefresh(m_roundRobin); > int qs = m_bankQueues[m_roundRobin].size(); > if (qs > 1) { > - g_system_ptr->getProfiler()->profileMemBankQ(m_version, qs-1); > + m_profiler_ptr->profileMemBankQ(qs-1); > } > if (qs > 0) { > m_idleCount = IDLECOUNT_MAX_VALUE; // we're not idle if anything is > queued > @@ -587,14 +600,14 @@ > issueRequest(m_roundRobin); > banksIssued++; > if (m_mem_fixed_delay) { > - g_system_ptr->getProfiler()->profileMemWaitCycles(m_version, > m_mem_fixed_delay); > + m_profiler_ptr->profileMemWaitCycles(m_mem_fixed_delay); > } > } > } > } > > // memWaitCycles is a redundant catch-all for the specific counters in > queueReady > - g_system_ptr->getProfiler()->profileMemWaitCycles(m_version, queueHeads - > banksIssued); > + m_profiler_ptr->profileMemWaitCycles(queueHeads - banksIssued); > > // Check input queue and move anything to bank queues if not full. > // Since this is done here at the end of the cycle, there will always > @@ -611,7 +624,7 @@ > m_input_queue.pop_front(); > m_bankQueues[bank].push_back(req); > } > - g_system_ptr->getProfiler()->profileMemInputQ(m_version, > m_input_queue.size()); > + m_profiler_ptr->profileMemInputQ(m_input_queue.size()); > } > } > > diff -r 6171341ed54d -r e1df8da6de6a src/mem/ruby/system/MemoryControl.hh > --- a/src/mem/ruby/system/MemoryControl.hh Mon Dec 21 08:29:40 2009 -0800 > +++ b/src/mem/ruby/system/MemoryControl.hh Mon Dec 21 08:29:40 2009 -0800 > @@ -42,7 +42,7 @@ > #include "mem/ruby/common/Global.hh" > #include "mem/gems_common/Map.hh" > #include "mem/ruby/common/Address.hh" > -#include "mem/ruby/profiler/Profiler.hh" > +#include "mem/ruby/profiler/MemCntrlProfiler.hh" > #include "mem/ruby/system/System.hh" > #include "mem/ruby/slicc_interface/Message.hh" > #include "mem/gems_common/util.hh" > @@ -99,6 +99,8 @@ > void printConfig (ostream& out); > void print (ostream& out) const; > void setDebug (int debugFlag); > + void clearStats() const; > + void printStats(ostream& out) const; > > > //added by SS > @@ -123,7 +125,6 @@ > > // data members > Consumer* m_consumer_ptr; // Consumer to signal a wakeup() > - int m_version; > string m_description; > int m_msg_counter; > int m_awakened; > @@ -178,6 +179,8 @@ > int m_ageCounter; // age of old requests; to detect starvation > int m_idleCount; // watchdog timer for shutting down > int m_debug; // turn on printf's > + > + MemCntrlProfiler* m_profiler_ptr; > }; > > #endif // MEMORY_CONTROL_H > > _______________________________________________ > m5-dev mailing list > [email protected] > http://m5sim.org/mailman/listinfo/m5-dev > > _______________________________________________ m5-dev mailing list [email protected] http://m5sim.org/mailman/listinfo/m5-dev
