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.
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
//
|
||||
// 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;
|
||||
|
||||
Profiler::~Profiler()
|
||||
{
|
||||
if (m_periodic_output_file_ptr != &cerr) {
|
||||
delete m_periodic_output_file_ptr;
|
||||
}
|
||||
delete m_requestProfileMap_ptr;
|
||||
}
|
||||
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;
|
||||
|
||||
void Profiler::init(const vector<string> & argv, vector<string> memory_control_names)
|
||||
{
|
||||
// added by SS
|
||||
vector<string>::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;
|
||||
int totalBanks = p->banks_per_rank *
|
||||
p->ranks_per_dimm *
|
||||
p->dimms_per_channel;
|
||||
|
||||
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();
|
||||
m_mc_profilers[mem_cntrl]->m_memBankCount.setSize(totalBanks);
|
||||
}
|
||||
|
||||
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<string> & argv, vector<string> 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<string>::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<long long int> 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<uint64> 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<string>::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 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_memory_control_profilers[(*it).c_str()] -> m_memBankCount.size(); bank++) {
|
||||
m_memory_control_profilers[(*it).c_str()] -> m_memBankCount[bank] = 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::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++;
|
||||
}
|
||||
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++; }
|
||||
|
||||
|
||||
Profiler *
|
||||
|
||||
@@ -80,22 +80,22 @@ class AddressProfiler;
|
||||
template <class KEY_TYPE, class VALUE_TYPE> 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<long long int> 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<uint64> 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<string> & argv, vector<string> 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;
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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, "");
|
||||
|
||||
@@ -114,6 +114,7 @@ RubySystem::RubySystem(const Params *p)
|
||||
|
||||
void RubySystem::init()
|
||||
{
|
||||
m_profiler_ptr->clearStats();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user