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

Reply via email to