# HG changeset patch # User Brad Beckmann <brad.beckm...@amd.com> # Date 1263536245 28800 # Node ID 412eb04d0909c94debbe76e07665792e8a0a4a18 # Parent af3701615ac52dc6050d7898b83a2540400eac24 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 af3701615ac5 -r 412eb04d0909 configs/ruby/MOESI_hammer.py --- a/configs/ruby/MOESI_hammer.py Thu Jan 14 22:17:25 2010 -0800 +++ b/configs/ruby/MOESI_hammer.py Thu Jan 14 22:17:25 2010 -0800 @@ -74,14 +74,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 af3701615ac5 -r 412eb04d0909 configs/ruby/Ruby.py --- a/configs/ruby/Ruby.py Thu Jan 14 22:17:25 2010 -0800 +++ b/configs/ruby/Ruby.py Thu Jan 14 22:17:25 2010 -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 af3701615ac5 -r 412eb04d0909 src/mem/ruby/profiler/CacheProfiler.cc --- a/src/mem/ruby/profiler/CacheProfiler.cc Thu Jan 14 22:17:25 2010 -0800 +++ b/src/mem/ruby/profiler/CacheProfiler.cc Thu Jan 14 22:17:25 2010 -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 af3701615ac5 -r 412eb04d0909 src/mem/ruby/profiler/CacheProfiler.hh --- a/src/mem/ruby/profiler/CacheProfiler.hh Thu Jan 14 22:17:25 2010 -0800 +++ b/src/mem/ruby/profiler/CacheProfiler.hh Thu Jan 14 22:17:25 2010 -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 af3701615ac5 -r 412eb04d0909 src/mem/ruby/profiler/MemCntrlProfiler.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/profiler/MemCntrlProfiler.cc Thu Jan 14 22:17:25 2010 -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 af3701615ac5 -r 412eb04d0909 src/mem/ruby/profiler/MemCntrlProfiler.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/profiler/MemCntrlProfiler.hh Thu Jan 14 22:17:25 2010 -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 af3701615ac5 -r 412eb04d0909 src/mem/ruby/profiler/Profiler.cc --- a/src/mem/ruby/profiler/Profiler.cc Thu Jan 14 22:17:25 2010 -0800 +++ b/src/mem/ruby/profiler/Profiler.cc Thu Jan 14 22:17:25 2010 -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 af3701615ac5 -r 412eb04d0909 src/mem/ruby/profiler/Profiler.hh --- a/src/mem/ruby/profiler/Profiler.hh Thu Jan 14 22:17:25 2010 -0800 +++ b/src/mem/ruby/profiler/Profiler.hh Thu Jan 14 22:17:25 2010 -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 af3701615ac5 -r 412eb04d0909 src/mem/ruby/profiler/Profiler.py --- a/src/mem/ruby/profiler/Profiler.py Thu Jan 14 22:17:25 2010 -0800 +++ b/src/mem/ruby/profiler/Profiler.py Thu Jan 14 22:17:25 2010 -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 af3701615ac5 -r 412eb04d0909 src/mem/ruby/profiler/SConscript --- a/src/mem/ruby/profiler/SConscript Thu Jan 14 22:17:25 2010 -0800 +++ b/src/mem/ruby/profiler/SConscript Thu Jan 14 22:17:25 2010 -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 af3701615ac5 -r 412eb04d0909 src/mem/ruby/system/Cache.py --- a/src/mem/ruby/system/Cache.py Thu Jan 14 22:17:25 2010 -0800 +++ b/src/mem/ruby/system/Cache.py Thu Jan 14 22:17:25 2010 -0800 @@ -9,4 +9,3 @@ latency = Param.Int(""); assoc = Param.Int(""); replacement_policy = Param.String("PSEUDO_LRU", ""); - cache_profiler = Param.CacheProfiler(""); diff -r af3701615ac5 -r 412eb04d0909 src/mem/ruby/system/CacheMemory.cc --- a/src/mem/ruby/system/CacheMemory.cc Thu Jan 14 22:17:25 2010 -0800 +++ b/src/mem/ruby/system/CacheMemory.cc Thu Jan 14 22:17:25 2010 -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 af3701615ac5 -r 412eb04d0909 src/mem/ruby/system/MemoryControl.cc --- a/src/mem/ruby/system/MemoryControl.cc Thu Jan 14 22:17:25 2010 -0800 +++ b/src/mem/ruby/system/MemoryControl.cc Thu Jan 14 22:17:25 2010 -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,6 +324,7 @@ void MemoryControl::printConfig (ostream& out) { + 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) { @@ -348,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); +} + // **************************************************************** @@ -394,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) { @@ -415,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; @@ -459,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; @@ -503,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; @@ -577,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 @@ -586,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 @@ -610,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 af3701615ac5 -r 412eb04d0909 src/mem/ruby/system/MemoryControl.hh --- a/src/mem/ruby/system/MemoryControl.hh Thu Jan 14 22:17:25 2010 -0800 +++ b/src/mem/ruby/system/MemoryControl.hh Thu Jan 14 22:17:25 2010 -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 m5-dev@m5sim.org http://m5sim.org/mailman/listinfo/m5-dev