From 2c9ca672dfe4a204ebe21c73b344d2939c0e0eff Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Fri, 29 Jan 2010 20:29:20 -0800 Subject: [PATCH] ruby: Memory Controller Profiler with new config system This patch includes a rather substantial change to the memory controller profiler in order to work with the new configuration system. Most noteably, the mem_cntrl_profiler no longer uses a string map, but instead a vector. Eventually this support should be removed from the main profiler and go into a separate object. Each memory controller should have a pointer to that new mem_cntrl profile object. --- configs/example/memtest-ruby.py | 26 ++- src/mem/ruby/profiler/Profiler.cc | 321 +++++++++++++++++---------- src/mem/ruby/profiler/Profiler.hh | 66 +++--- src/mem/ruby/profiler/Profiler.py | 4 + src/mem/ruby/system/MemoryControl.cc | 35 +-- src/mem/ruby/system/MemoryControl.hh | 2 +- src/mem/ruby/system/MemoryControl.py | 1 + src/mem/ruby/system/System.cc | 1 + 8 files changed, 278 insertions(+), 178 deletions(-) diff --git a/configs/example/memtest-ruby.py b/configs/example/memtest-ruby.py index abc22a93b..c610a1c62 100644 --- a/configs/example/memtest-ruby.py +++ b/configs/example/memtest-ruby.py @@ -135,9 +135,11 @@ for (i, cpu) in enumerate(cpus): L1DcacheMemory = l1d_cache, L2cacheMemory = l2_cache) + mem_cntrl = RubyMemoryControl(version = i) + dir_cntrl = Directory_Controller(version = i, directory = RubyDirectoryMemory(), - memBuffer = RubyMemoryControl()) + memBuffer = mem_cntrl) dma_cntrl = DMA_Controller(version = i, dma_sequencer = DMASequencer()) @@ -167,13 +169,27 @@ network = SimpleNetwork(topology = makeCrossbar(l1_cntrl_nodes + \ mem_size_mb = sum([int(dir_cntrl.directory.size_mb) \ for dir_cntrl in dir_cntrl_nodes]) +# +# determine the number of memory controllers and other memory controller +# parameters for the profiler +# +mcCount = len(dir_cntrl_nodes) +banksPerRank = dir_cntrl_nodes[0].memBuffer.banks_per_rank +ranksPerDimm = dir_cntrl_nodes[0].memBuffer.ranks_per_dimm +dimmsPerChannel = dir_cntrl_nodes[0].memBuffer.dimms_per_channel + +ruby_profiler = RubyProfiler(mem_cntrl_count = mcCount, + banks_per_rank = banksPerRank, + ranks_per_dimm = ranksPerDimm, + dimms_per_channel = dimmsPerChannel) + system.ruby = RubySystem(clock = '1GHz', network = network, - profiler = RubyProfiler(), + profiler = ruby_profiler, tracer = RubyTracer(), - debug = RubyDebug(filter_string = 'qQin', - verbosity_string = 'high', - protocol_trace = True), + debug = RubyDebug(filter_string = 'none', + verbosity_string = 'none', + protocol_trace = False), mem_size_mb = mem_size_mb) diff --git a/src/mem/ruby/profiler/Profiler.cc b/src/mem/ruby/profiler/Profiler.cc index c6fbd1aa4..0a65f88fc 100644 --- a/src/mem/ruby/profiler/Profiler.cc +++ b/src/mem/ruby/profiler/Profiler.cc @@ -88,57 +88,40 @@ Profiler::Profiler(const Params *p) m_hot_lines = p->hot_lines; m_all_instructions = p->all_instructions; - RubySystem::m_profiler_ptr = this; -} - -Profiler::~Profiler() -{ - if (m_periodic_output_file_ptr != &cerr) { - delete m_periodic_output_file_ptr; - } - delete m_requestProfileMap_ptr; -} + // + // 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); + } -void Profiler::init(const vector & argv, vector memory_control_names) -{ - // added by SS - vector::iterator it; - memory_control_profiler* mcp; - m_memory_control_names = memory_control_names; -// printf ( "Here in Profiler::init \n"); - for ( it=memory_control_names.begin() ; it < memory_control_names.end(); it++ ){ -// printf ( "Here in Profiler::init memory control name %s \n", (*it).c_str()); - mcp = new memory_control_profiler; - mcp->m_memReq = 0; - mcp->m_memBankBusy = 0; - mcp->m_memBusBusy = 0; - mcp->m_memReadWriteBusy = 0; - mcp->m_memDataBusBusy = 0; - mcp->m_memTfawBusy = 0; - mcp->m_memRefresh = 0; - mcp->m_memRead = 0; - mcp->m_memWrite = 0; - mcp->m_memWaitCycles = 0; - mcp->m_memInputQ = 0; - mcp->m_memBankQ = 0; - mcp->m_memArbWait = 0; - mcp->m_memRandBusy = 0; - mcp->m_memNotOld = 0; - - mcp->m_banks_per_rank = RubySystem::getMemoryControl((*it).c_str())->getBanksPerRank(); - mcp->m_ranks_per_dimm = RubySystem::getMemoryControl((*it).c_str())->getRanksPerDimm(); - mcp->m_dimms_per_channel = RubySystem::getMemoryControl((*it).c_str())->getDimmsPerChannel(); - - int totalBanks = mcp->m_banks_per_rank - * mcp->m_ranks_per_dimm - * mcp->m_dimms_per_channel; - - mcp->m_memBankCount.setSize(totalBanks); - - m_memory_control_profilers [(*it).c_str()] = mcp; - } - - clearStats(); m_hot_lines = false; m_all_instructions = false; @@ -153,6 +136,21 @@ void Profiler::init(const vector & argv, vector memory_control_n } } +Profiler::~Profiler() +{ + if (m_periodic_output_file_ptr != &cerr) { + 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; +} + void Profiler::wakeup() { // FIXME - avoid the repeated code @@ -170,17 +168,51 @@ void Profiler::wakeup() integer_t transactions_started = m_perProcStartTransaction.sum(); integer_t transactions_ended = m_perProcEndTransaction.sum(); - (*m_periodic_output_file_ptr) << "ruby_cycles: " << g_eventQueue_ptr->getTime()-m_ruby_start << endl; - (*m_periodic_output_file_ptr) << "total_misses: " << total_misses << " " << m_perProcTotalMisses << endl; - (*m_periodic_output_file_ptr) << "simics_cycles_executed: " << simics_cycles_executed << " " << perProcCycleCount << endl; - (*m_periodic_output_file_ptr) << "transactions_started: " << transactions_started << " " << m_perProcStartTransaction << endl; - (*m_periodic_output_file_ptr) << "transactions_ended: " << transactions_ended << " " << m_perProcEndTransaction << endl; - (*m_periodic_output_file_ptr) << "mbytes_resident: " << process_memory_resident() << endl; - (*m_periodic_output_file_ptr) << "mbytes_total: " << process_memory_total() << endl; + (*m_periodic_output_file_ptr) << "ruby_cycles: " + << g_eventQueue_ptr->getTime()-m_ruby_start + << endl; + + (*m_periodic_output_file_ptr) << "total_misses: " + << total_misses + << " " + << m_perProcTotalMisses + << endl; + + (*m_periodic_output_file_ptr) << "simics_cycles_executed: " + << simics_cycles_executed + << " " + << perProcCycleCount + << endl; + + (*m_periodic_output_file_ptr) << "transactions_started: " + << transactions_started + << " " + << m_perProcStartTransaction + << endl; + + (*m_periodic_output_file_ptr) << "transactions_ended: " + << transactions_ended + << " " + << m_perProcEndTransaction + << endl; + + (*m_periodic_output_file_ptr) << "mbytes_resident: " + << process_memory_resident() + << endl; + + (*m_periodic_output_file_ptr) << "mbytes_total: " + << process_memory_total() + << endl; + if (process_memory_total() > 0) { - (*m_periodic_output_file_ptr) << "resident_ratio: " << process_memory_resident()/process_memory_total() << endl; + (*m_periodic_output_file_ptr) << "resident_ratio: " + << process_memory_resident()/process_memory_total() + << endl; } - (*m_periodic_output_file_ptr) << "miss_latency: " << m_allMissLatencyHistogram << endl; + + (*m_periodic_output_file_ptr) << "miss_latency: " + << m_allMissLatencyHistogram + << endl; *m_periodic_output_file_ptr << endl; @@ -207,7 +239,9 @@ void Profiler::setPeriodicStatsFile(const string& filename) void Profiler::setPeriodicStatsInterval(integer_t period) { - cout << "Recording periodic statistics every " << m_stats_period << " Ruby cycles" << endl; + cout << "Recording periodic statistics every " << m_stats_period + << " Ruby cycles" << endl; + m_stats_period = period; g_eventQueue_ptr->scheduleEvent(this, 1); } @@ -271,7 +305,8 @@ void Profiler::printStats(ostream& out, bool short_stats) out << "mbytes_resident: " << process_memory_resident() << endl; out << "mbytes_total: " << process_memory_total() << endl; if (process_memory_total() > 0) { - out << "resident_ratio: " << process_memory_resident()/process_memory_total() << endl; + out << "resident_ratio: " + << process_memory_resident()/process_memory_total() << endl; } out << endl; @@ -326,30 +361,30 @@ void Profiler::printStats(ostream& out, bool short_stats) out << endl; - vector::iterator it; - - for ( it=m_memory_control_names.begin() ; it < m_memory_control_names.end(); it++ ){ - long long int m_memReq = m_memory_control_profilers[(*it).c_str()] -> m_memReq; - long long int m_memRefresh = m_memory_control_profilers[(*it).c_str()] -> m_memRefresh; - long long int m_memInputQ = m_memory_control_profilers[(*it).c_str()] -> m_memInputQ; - long long int m_memBankQ = m_memory_control_profilers[(*it).c_str()] -> m_memBankQ; - long long int m_memWaitCycles = m_memory_control_profilers[(*it).c_str()] -> m_memWaitCycles; - long long int m_memRead = m_memory_control_profilers[(*it).c_str()] -> m_memRead; - long long int m_memWrite = m_memory_control_profilers[(*it).c_str()] -> m_memWrite; - long long int m_memBankBusy = m_memory_control_profilers[(*it).c_str()] -> m_memBankBusy; - long long int m_memRandBusy = m_memory_control_profilers[(*it).c_str()] -> m_memRandBusy; - long long int m_memNotOld = m_memory_control_profilers[(*it).c_str()] -> m_memNotOld; - long long int m_memArbWait = m_memory_control_profilers[(*it).c_str()] -> m_memArbWait; - long long int m_memBusBusy = m_memory_control_profilers[(*it).c_str()] -> m_memBusBusy; - long long int m_memTfawBusy = m_memory_control_profilers[(*it).c_str()] -> m_memTfawBusy; - long long int m_memReadWriteBusy = m_memory_control_profilers[(*it).c_str()] -> m_memReadWriteBusy; - long long int m_memDataBusBusy = m_memory_control_profilers[(*it).c_str()] -> m_memDataBusBusy; - Vector m_memBankCount = m_memory_control_profilers[(*it).c_str()] -> m_memBankCount; + 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 m_memBankCount = m_mc_profilers[mem_cntrl]->m_memBankCount; if (m_memReq || m_memRefresh) { // if there's a memory controller at all - long long int total_stalls = m_memInputQ + m_memBankQ + m_memWaitCycles; + uint64 total_stalls = m_memInputQ + m_memBankQ + m_memWaitCycles; double stallsPerReq = total_stalls * 1.0 / m_memReq; - out << "Memory control " << (*it) << ":" << endl; + 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; @@ -609,25 +644,29 @@ void Profiler::clearStats() //added by SS vector::iterator it; - for ( it=m_memory_control_names.begin() ; it < m_memory_control_names.end(); it++ ){ - m_memory_control_profilers[(*it).c_str()] -> m_memReq = 0; - m_memory_control_profilers[(*it).c_str()] -> m_memBankBusy = 0; - m_memory_control_profilers[(*it).c_str()] -> m_memBusBusy = 0; - m_memory_control_profilers[(*it).c_str()] -> m_memTfawBusy = 0; - m_memory_control_profilers[(*it).c_str()] -> m_memReadWriteBusy = 0; - m_memory_control_profilers[(*it).c_str()] -> m_memDataBusBusy = 0; - m_memory_control_profilers[(*it).c_str()] -> m_memRefresh = 0; - m_memory_control_profilers[(*it).c_str()] -> m_memRead = 0; - m_memory_control_profilers[(*it).c_str()] -> m_memWrite = 0; - m_memory_control_profilers[(*it).c_str()] -> m_memWaitCycles = 0; - m_memory_control_profilers[(*it).c_str()] -> m_memInputQ = 0; - m_memory_control_profilers[(*it).c_str()] -> m_memBankQ = 0; - m_memory_control_profilers[(*it).c_str()] -> m_memArbWait = 0; - m_memory_control_profilers[(*it).c_str()] -> m_memRandBusy = 0; - m_memory_control_profilers[(*it).c_str()] -> m_memNotOld = 0; - - for (int bank=0; bank < m_memory_control_profilers[(*it).c_str()] -> m_memBankCount.size(); bank++) { - m_memory_control_profilers[(*it).c_str()] -> m_memBankCount[bank] = 0; + 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 @@ -823,26 +862,66 @@ int64 Profiler::getTotalTransactionsExecuted() const { } // For MemoryControl: -void Profiler::profileMemReq(string name, int bank) { -// printf("name is %s", name.c_str()); - assert(m_memory_control_profilers.count(name) == 1); - m_memory_control_profilers[name] -> m_memReq++; - m_memory_control_profilers[name] -> m_memBankCount[bank]++; -} -void Profiler::profileMemBankBusy(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memBankBusy++; } -void Profiler::profileMemBusBusy(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memBusBusy++; } -void Profiler::profileMemReadWriteBusy(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memReadWriteBusy++; } -void Profiler::profileMemDataBusBusy(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memDataBusBusy++; } -void Profiler::profileMemTfawBusy(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memTfawBusy++; } -void Profiler::profileMemRefresh(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memRefresh++; } -void Profiler::profileMemRead(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memRead++; } -void Profiler::profileMemWrite(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memWrite++; } -void Profiler::profileMemWaitCycles(string name, int cycles) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memWaitCycles += cycles; } -void Profiler::profileMemInputQ(string name, int cycles) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memInputQ += cycles; } -void Profiler::profileMemBankQ(string name, int cycles) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memBankQ += cycles; } -void Profiler::profileMemArbWait(string name, int cycles) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memArbWait += cycles; } -void Profiler::profileMemRandBusy(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memRandBusy++; } -void Profiler::profileMemNotOld(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memNotOld++; } +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 * diff --git a/src/mem/ruby/profiler/Profiler.hh b/src/mem/ruby/profiler/Profiler.hh index 8bc8de591..8c5e54f51 100644 --- a/src/mem/ruby/profiler/Profiler.hh +++ b/src/mem/ruby/profiler/Profiler.hh @@ -80,22 +80,22 @@ class AddressProfiler; template class Map; struct memory_control_profiler { - long long int m_memReq; - long long int m_memBankBusy; - long long int m_memBusBusy; - long long int m_memTfawBusy; - long long int m_memReadWriteBusy; - long long int m_memDataBusBusy; - long long int m_memRefresh; - long long int m_memRead; - long long int m_memWrite; - long long int m_memWaitCycles; - long long int m_memInputQ; - long long int m_memBankQ; - long long int m_memArbWait; - long long int m_memRandBusy; - long long int m_memNotOld; - Vector m_memBankCount; + 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 m_memBankCount; int m_banks_per_rank; int m_ranks_per_dimm; int m_dimms_per_channel; @@ -108,8 +108,6 @@ public: typedef RubyProfilerParams Params; Profiler(const Params *); - void init(const vector & argv, vector memory_control_names); - // Destructor ~Profiler(); @@ -173,21 +171,21 @@ public: } // added for MemoryControl: - void profileMemReq(string name, int bank); - void profileMemBankBusy(string name); - void profileMemBusBusy(string name); - void profileMemTfawBusy(string name); - void profileMemReadWriteBusy(string name); - void profileMemDataBusBusy(string name); - void profileMemRefresh(string name); - void profileMemRead(string name); - void profileMemWrite(string name); - void profileMemWaitCycles(string name, int cycles); - void profileMemInputQ(string name, int cycles); - void profileMemBankQ(string name, int cycles); - void profileMemArbWait(string name, int cycles); - void profileMemRandBusy(string name); - void profileMemNotOld(string name); + 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; } @@ -259,7 +257,7 @@ private: // added for MemoryControl: //added by SS - map< string, memory_control_profiler* > m_memory_control_profilers; + Vector < memory_control_profiler* > m_mc_profilers; //added by SS bool m_hot_lines; diff --git a/src/mem/ruby/profiler/Profiler.py b/src/mem/ruby/profiler/Profiler.py index 7585d4978..9210c3c0b 100644 --- a/src/mem/ruby/profiler/Profiler.py +++ b/src/mem/ruby/profiler/Profiler.py @@ -6,6 +6,10 @@ class RubyProfiler(SimObject): cxx_class = 'Profiler' hot_lines = Param.Bool(False, "") all_instructions = Param.Bool(False, "") + 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' diff --git a/src/mem/ruby/system/MemoryControl.cc b/src/mem/ruby/system/MemoryControl.cc index 5a6c9e34c..0a7b93e6f 100644 --- a/src/mem/ruby/system/MemoryControl.cc +++ b/src/mem/ruby/system/MemoryControl.cc @@ -154,6 +154,7 @@ ostream& operator<<(ostream& out, const MemoryControl& obj) 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; @@ -266,8 +267,8 @@ void MemoryControl::enqueueMemRef (MemoryNode& memRef) { printf("New memory request%7d: 0x%08llx %c arrived at %10lld ", m_msg_counter, addr, is_mem_read? 'R':'W', at); printf("bank =%3x\n", bank); } -// printf ("m_name is %s \n", m_name.c_str()); - g_system_ptr->getProfiler()->profileMemReq(m_name, bank); + + g_system_ptr->getProfiler()->profileMemReq(m_version, bank); m_input_queue.push_back(memRef); if (!m_awakened) { g_eventQueue_ptr->scheduleEvent(this, 1); @@ -393,19 +394,19 @@ int MemoryControl::getRank (int bank) { bool MemoryControl::queueReady (int bank) { if ((m_bankBusyCounter[bank] > 0) && !m_mem_fixed_delay) { - g_system_ptr->getProfiler()->profileMemBankBusy(m_name); + g_system_ptr->getProfiler()->profileMemBankBusy(m_version); //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_name); + g_system_ptr->getProfiler()->profileMemRandBusy(m_version); 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_name); + g_system_ptr->getProfiler()->profileMemNotOld(m_version); return false; } if (m_busBusyCounter_Basic == m_basic_bus_busy_time) { @@ -414,26 +415,26 @@ bool MemoryControl::queueReady (int bank) { // 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_name, 1); + g_system_ptr->getProfiler()->profileMemArbWait(m_version, 1); return false; } if (m_busBusyCounter_Basic > 0) { - g_system_ptr->getProfiler()->profileMemBusBusy(m_name); + g_system_ptr->getProfiler()->profileMemBusBusy(m_version); return false; } int rank = getRank(bank); if (m_tfaw_count[rank] >= ACTIVATE_PER_TFAW) { - g_system_ptr->getProfiler()->profileMemTfawBusy(m_name); + g_system_ptr->getProfiler()->profileMemTfawBusy(m_version); return false; } bool write = !m_bankQueues[bank].front().m_is_mem_read; if (write && (m_busBusyCounter_Write > 0)) { - g_system_ptr->getProfiler()->profileMemReadWriteBusy(m_name); + g_system_ptr->getProfiler()->profileMemReadWriteBusy(m_version); return false; } if (!write && (rank != m_busBusy_WhichRank) && (m_busBusyCounter_ReadNewRank > 0)) { - g_system_ptr->getProfiler()->profileMemDataBusBusy(m_name); + g_system_ptr->getProfiler()->profileMemDataBusBusy(m_version); return false; } return true; @@ -458,7 +459,7 @@ bool MemoryControl::issueRefresh (int bank) { //uint64 current_time = g_eventQueue_ptr->getTime(); //printf(" Refresh bank %3x at %lld\n", bank, current_time); //} - g_system_ptr->getProfiler()->profileMemRefresh(m_name); + g_system_ptr->getProfiler()->profileMemRefresh(m_version); m_need_refresh--; m_refresh_bank++; if (m_refresh_bank >= m_total_banks) m_refresh_bank = 0; @@ -502,12 +503,12 @@ void MemoryControl::issueRequest (int bank) { m_bankBusyCounter[bank] = m_bank_busy_time; m_busBusy_WhichRank = rank; if (req.m_is_mem_read) { - g_system_ptr->getProfiler()->profileMemRead(m_name); + g_system_ptr->getProfiler()->profileMemRead(m_version); 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_name); + g_system_ptr->getProfiler()->profileMemWrite(m_version); m_busBusyCounter_Basic = m_basic_bus_busy_time; m_busBusyCounter_Write = m_basic_bus_busy_time; m_busBusyCounter_ReadNewRank = m_basic_bus_busy_time; @@ -576,7 +577,7 @@ void MemoryControl::executeCycle () { issueRefresh(m_roundRobin); int qs = m_bankQueues[m_roundRobin].size(); if (qs > 1) { - g_system_ptr->getProfiler()->profileMemBankQ(m_name, qs-1); + g_system_ptr->getProfiler()->profileMemBankQ(m_version, qs-1); } if (qs > 0) { m_idleCount = IDLECOUNT_MAX_VALUE; // we're not idle if anything is queued @@ -585,14 +586,14 @@ void MemoryControl::executeCycle () { issueRequest(m_roundRobin); banksIssued++; if (m_mem_fixed_delay) { - g_system_ptr->getProfiler()->profileMemWaitCycles(m_name, m_mem_fixed_delay); + g_system_ptr->getProfiler()->profileMemWaitCycles(m_version, m_mem_fixed_delay); } } } } // memWaitCycles is a redundant catch-all for the specific counters in queueReady - g_system_ptr->getProfiler()->profileMemWaitCycles(m_name, queueHeads - banksIssued); + g_system_ptr->getProfiler()->profileMemWaitCycles(m_version, 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 @@ -609,7 +610,7 @@ void MemoryControl::executeCycle () { m_input_queue.pop_front(); m_bankQueues[bank].push_back(req); } - g_system_ptr->getProfiler()->profileMemInputQ(m_name, m_input_queue.size()); + g_system_ptr->getProfiler()->profileMemInputQ(m_version, m_input_queue.size()); } } diff --git a/src/mem/ruby/system/MemoryControl.hh b/src/mem/ruby/system/MemoryControl.hh index 1570e81cd..c875c0bbc 100644 --- a/src/mem/ruby/system/MemoryControl.hh +++ b/src/mem/ruby/system/MemoryControl.hh @@ -123,7 +123,7 @@ private: // data members Consumer* m_consumer_ptr; // Consumer to signal a wakeup() - string m_name; + int m_version; string m_description; int m_msg_counter; int m_awakened; diff --git a/src/mem/ruby/system/MemoryControl.py b/src/mem/ruby/system/MemoryControl.py index 6c8109728..2a83584b3 100644 --- a/src/mem/ruby/system/MemoryControl.py +++ b/src/mem/ruby/system/MemoryControl.py @@ -4,6 +4,7 @@ from m5.SimObject import SimObject class RubyMemoryControl(SimObject): type = 'RubyMemoryControl' cxx_class = 'MemoryControl' + version = Param.Int(""); mem_bus_cycle_multiplier = Param.Int(10, ""); banks_per_rank = Param.Int(8, ""); ranks_per_dimm = Param.Int(2, ""); diff --git a/src/mem/ruby/system/System.cc b/src/mem/ruby/system/System.cc index ec7218680..4dcca2f83 100644 --- a/src/mem/ruby/system/System.cc +++ b/src/mem/ruby/system/System.cc @@ -114,6 +114,7 @@ RubySystem::RubySystem(const Params *p) void RubySystem::init() { + m_profiler_ptr->clearStats(); } -- 2.30.2