def create_system(options, system, piobus = None, dma_ports = []):
- system.ruby = RubySystem(stats_filename = options.ruby_stats,
- no_mem_vec = options.use_map)
+ system.ruby = RubySystem(no_mem_vec = options.use_map)
ruby = system.ruby
protocol = buildEnv['PROTOCOL']
phys_mem_size = sum(map(lambda r: r.size(), system.mem_ranges))
assert(total_mem_size.value == phys_mem_size)
- ruby_profiler = RubyProfiler(ruby_system = ruby,
- num_of_sequencers = len(cpu_sequencers))
ruby.network = network
- ruby.profiler = ruby_profiler
ruby.mem_size = total_mem_size
ruby._cpu_ruby_ports = cpu_sequencers
+ ruby.num_of_sequencers = len(cpu_sequencers)
ruby.random_seed = options.random_seed
ccprintf(out, "%s] %s", copy, m_name);
}
-void
-MessageBuffer::printStats(ostream& out)
-{
- out << "MessageBuffer: " << m_name << " stats - msgs:" << m_msg_counter
- << " full:" << m_not_avail_count << endl;
-}
-
bool
MessageBuffer::isReady() const
{
void clear();
void print(std::ostream& out) const;
- void printStats(std::ostream& out);
void clearStats() { m_not_avail_count = 0; m_msg_counter = 0; }
void setIncomingLink(int link_id) { m_input_link_id = link_id; }
//added by SS
void setHotLines(bool hot_lines);
void setAllInstructions(bool all_instructions);
+ void regStats(const std::string &name) {}
+ void collateStats() {}
private:
// Private copy constructor and assignment operator
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 1999-2013 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
using namespace std;
using m5::stl_helpers::operator<<;
-Profiler::Profiler(const Params *p)
- : SimObject(p)
+Profiler::Profiler(const RubySystemParams *p)
+ : m_IncompleteTimes(MachineType_NUM)
{
- m_inst_profiler_ptr = NULL;
- m_address_profiler_ptr = NULL;
- m_real_time_start_time = time(NULL); // Not reset in clearStats()
-
m_hot_lines = p->hot_lines;
m_all_instructions = p->all_instructions;
- m_num_of_sequencers = p->num_of_sequencers;
-
- m_hot_lines = false;
- m_all_instructions = false;
-
- m_address_profiler_ptr = new AddressProfiler(m_num_of_sequencers);
+ m_address_profiler_ptr = new AddressProfiler(p->num_of_sequencers);
m_address_profiler_ptr->setHotLines(m_hot_lines);
m_address_profiler_ptr->setAllInstructions(m_all_instructions);
if (m_all_instructions) {
- m_inst_profiler_ptr = new AddressProfiler(m_num_of_sequencers);
+ m_inst_profiler_ptr = new AddressProfiler(p->num_of_sequencers);
m_inst_profiler_ptr->setHotLines(m_hot_lines);
m_inst_profiler_ptr->setAllInstructions(m_all_instructions);
}
-
- p->ruby_system->registerProfiler(this);
}
Profiler::~Profiler()
}
void
-Profiler::print(ostream& out) const
+Profiler::regStats(const std::string &pName)
{
- out << "[Profiler]";
-}
-
-void
-Profiler::printRequestProfile(ostream &out) const
-{
- out << "Request vs. RubySystem State Profile" << endl;
- out << "--------------------------------" << endl;
- out << endl;
+ if (!m_all_instructions) {
+ m_address_profiler_ptr->regStats(pName);
+ }
- map<string, uint64_t> m_requestProfileMap;
- uint64_t m_requests = 0;
+ if (m_all_instructions) {
+ m_inst_profiler_ptr->regStats(pName);
+ }
- for (uint32_t i = 0; i < MachineType_NUM; i++) {
- for (map<uint32_t, AbstractController*>::iterator it =
- g_abs_controls[i].begin();
- it != g_abs_controls[i].end(); ++it) {
+ delayHistogram
+ .init(10)
+ .name(pName + ".delayHist")
+ .desc("delay histogram for all message")
+ .flags(Stats::nozero | Stats::pdf | Stats::oneline);
- AbstractController *ctr = (*it).second;
- map<string, uint64_t> mp = ctr->getRequestProfileMap();
+ uint32_t numVNets = Network::getNumberOfVirtualNetworks();
+ for (int i = 0; i < numVNets; i++) {
+ delayVCHistogram.push_back(new Stats::Histogram());
+ delayVCHistogram[i]
+ ->init(10)
+ .name(pName + csprintf(".delayVCHist.vnet_%i", i))
+ .desc(csprintf("delay histogram for vnet_%i", i))
+ .flags(Stats::nozero | Stats::pdf | Stats::oneline);
+ }
- for (map<string, uint64_t>::iterator jt = mp.begin();
- jt != mp.end(); ++jt) {
+ m_outstandReqHist
+ .init(10)
+ .name(pName + ".outstanding_req_hist")
+ .desc("")
+ .flags(Stats::nozero | Stats::pdf | Stats::oneline);
+
+ m_latencyHist
+ .init(10)
+ .name(pName + ".latency_hist")
+ .desc("")
+ .flags(Stats::nozero | Stats::pdf | Stats::oneline);
+
+ m_hitLatencyHist
+ .init(10)
+ .name(pName + ".hit_latency_hist")
+ .desc("")
+ .flags(Stats::nozero | Stats::pdf | Stats::oneline);
+
+ m_missLatencyHist
+ .init(10)
+ .name(pName + ".miss_latency_hist")
+ .desc("")
+ .flags(Stats::nozero | Stats::pdf | Stats::oneline);
- map<string, uint64_t>::iterator kt =
- m_requestProfileMap.find((*jt).first);
- if (kt != m_requestProfileMap.end()) {
- (*kt).second += (*jt).second;
- } else {
- m_requestProfileMap[(*jt).first] = (*jt).second;
- }
- }
+ for (int i = 0; i < RubyRequestType_NUM; i++) {
+ m_typeLatencyHist.push_back(new Stats::Histogram());
+ m_typeLatencyHist[i]
+ ->init(10)
+ .name(pName + csprintf(".%s.latency_hist",
+ RubyRequestType(i)))
+ .desc("")
+ .flags(Stats::nozero | Stats::pdf | Stats::oneline);
+
+ m_hitTypeLatencyHist.push_back(new Stats::Histogram());
+ m_hitTypeLatencyHist[i]
+ ->init(10)
+ .name(pName + csprintf(".%s.hit_latency_hist",
+ RubyRequestType(i)))
+ .desc("")
+ .flags(Stats::nozero | Stats::pdf | Stats::oneline);
+
+ m_missTypeLatencyHist.push_back(new Stats::Histogram());
+ m_missTypeLatencyHist[i]
+ ->init(10)
+ .name(pName + csprintf(".%s.miss_latency_hist",
+ RubyRequestType(i)))
+ .desc("")
+ .flags(Stats::nozero | Stats::pdf | Stats::oneline);
+ }
- m_requests += ctr->getRequestCount();
- }
+ for (int i = 0; i < MachineType_NUM; i++) {
+ m_hitMachLatencyHist.push_back(new Stats::Histogram());
+ m_hitMachLatencyHist[i]
+ ->init(10)
+ .name(pName + csprintf(".%s.hit_mach_latency_hist",
+ MachineType(i)))
+ .desc("")
+ .flags(Stats::nozero | Stats::pdf | Stats::oneline);
+
+ m_missMachLatencyHist.push_back(new Stats::Histogram());
+ m_missMachLatencyHist[i]
+ ->init(10)
+ .name(pName + csprintf(".%s.miss_mach_latency_hist",
+ MachineType(i)))
+ .desc("")
+ .flags(Stats::nozero | Stats::pdf | Stats::oneline);
+
+ m_IssueToInitialDelayHist.push_back(new Stats::Histogram());
+ m_IssueToInitialDelayHist[i]
+ ->init(10)
+ .name(pName + csprintf(
+ ".%s.miss_latency_hist.issue_to_initial_request",
+ MachineType(i)))
+ .desc("")
+ .flags(Stats::nozero | Stats::pdf | Stats::oneline);
+
+ m_InitialToForwardDelayHist.push_back(new Stats::Histogram());
+ m_InitialToForwardDelayHist[i]
+ ->init(10)
+ .name(pName + csprintf(".%s.miss_latency_hist.initial_to_forward",
+ MachineType(i)))
+ .desc("")
+ .flags(Stats::nozero | Stats::pdf | Stats::oneline);
+
+ m_ForwardToFirstResponseDelayHist.push_back(new Stats::Histogram());
+ m_ForwardToFirstResponseDelayHist[i]
+ ->init(10)
+ .name(pName + csprintf(
+ ".%s.miss_latency_hist.forward_to_first_response",
+ MachineType(i)))
+ .desc("")
+ .flags(Stats::nozero | Stats::pdf | Stats::oneline);
+
+ m_FirstResponseToCompletionDelayHist.push_back(new Stats::Histogram());
+ m_FirstResponseToCompletionDelayHist[i]
+ ->init(10)
+ .name(pName + csprintf(
+ ".%s.miss_latency_hist.first_response_to_completion",
+ MachineType(i)))
+ .desc("")
+ .flags(Stats::nozero | Stats::pdf | Stats::oneline);
+
+ m_IncompleteTimes[i]
+ .name(pName + csprintf(".%s.incomplete_times", MachineType(i)))
+ .desc("")
+ .flags(Stats::nozero);
}
- map<string, uint64_t>::const_iterator i = m_requestProfileMap.begin();
- map<string, uint64_t>::const_iterator end = m_requestProfileMap.end();
- for (; i != end; ++i) {
- const string &key = i->first;
- uint64_t count = i->second;
-
- double percent = (100.0 * double(count)) / double(m_requests);
- vector<string> items;
- tokenize(items, key, ':');
- vector<string>::iterator j = items.begin();
- vector<string>::iterator end = items.end();
- for (; j != end; ++i)
- out << setw(10) << *j;
- out << setw(11) << count;
- out << setw(14) << percent << endl;
+ for (int i = 0; i < RubyRequestType_NUM; i++) {
+ m_hitTypeMachLatencyHist.push_back(std::vector<Stats::Histogram *>());
+ m_missTypeMachLatencyHist.push_back(std::vector<Stats::Histogram *>());
+
+ for (int j = 0; j < MachineType_NUM; j++) {
+ m_hitTypeMachLatencyHist[i].push_back(new Stats::Histogram());
+ m_hitTypeMachLatencyHist[i][j]
+ ->init(10)
+ .name(pName + csprintf(".%s.%s.hit_type_mach_latency_hist",
+ RubyRequestType(i), MachineType(j)))
+ .desc("")
+ .flags(Stats::nozero | Stats::pdf | Stats::oneline);
+
+ m_missTypeMachLatencyHist[i].push_back(new Stats::Histogram());
+ m_missTypeMachLatencyHist[i][j]
+ ->init(10)
+ .name(pName + csprintf(".%s.%s.miss_type_mach_latency_hist",
+ RubyRequestType(i), MachineType(j)))
+ .desc("")
+ .flags(Stats::nozero | Stats::pdf | Stats::oneline);
+ }
}
- out << endl;
}
void
-Profiler::printDelayProfile(ostream &out) const
+Profiler::collateStats()
{
- out << "Message Delayed Cycles" << endl;
- out << "----------------------" << endl;
+ if (!m_all_instructions) {
+ m_address_profiler_ptr->collateStats();
+ }
- uint32_t numVNets = Network::getNumberOfVirtualNetworks();
- Histogram delayHistogram;
- std::vector<Histogram> delayVCHistogram(numVNets);
+ if (m_all_instructions) {
+ m_inst_profiler_ptr->collateStats();
+ }
+ uint32_t numVNets = Network::getNumberOfVirtualNetworks();
for (uint32_t i = 0; i < MachineType_NUM; i++) {
for (map<uint32_t, AbstractController*>::iterator it =
g_abs_controls[i].begin();
delayHistogram.add(ctr->getDelayHist());
for (uint32_t i = 0; i < numVNets; i++) {
- delayVCHistogram[i].add(ctr->getDelayVCHist(i));
+ delayVCHistogram[i]->add(ctr->getDelayVCHist(i));
}
}
}
- out << "Total_delay_cycles: " << delayHistogram << endl;
-
- for (int i = 0; i < numVNets; i++) {
- out << " virtual_network_" << i << "_delay_cycles: "
- << delayVCHistogram[i] << endl;
- }
-}
-
-void
-Profiler::printOutstandingReqProfile(ostream &out) const
-{
- Histogram sequencerRequests;
-
for (uint32_t i = 0; i < MachineType_NUM; i++) {
for (map<uint32_t, AbstractController*>::iterator it =
- g_abs_controls[i].begin();
- it != g_abs_controls[i].end(); ++it) {
+ g_abs_controls[i].begin();
+ it != g_abs_controls[i].end(); ++it) {
AbstractController *ctr = (*it).second;
Sequencer *seq = ctr->getSequencer();
if (seq != NULL) {
- sequencerRequests.add(seq->getOutstandReqHist());
+ m_outstandReqHist.add(seq->getOutstandReqHist());
}
}
}
- out << "sequencer_requests_outstanding: "
- << sequencerRequests << endl;
-}
-
-void
-Profiler::printMissLatencyProfile(ostream &out) const
-{
- // Collate the miss latencies histograms from all the sequencers
- Histogram latency_hist;
- std::vector<Histogram> type_latency_hist(RubyRequestType_NUM);
-
- Histogram hit_latency_hist;
- std::vector<Histogram> hit_type_latency_hist(RubyRequestType_NUM);
-
- std::vector<Histogram> hit_mach_latency_hist(MachineType_NUM);
- std::vector<std::vector<Histogram> >
- hit_type_mach_latency_hist(RubyRequestType_NUM,
- std::vector<Histogram>(MachineType_NUM));
-
- Histogram miss_latency_hist;
- std::vector<Histogram> miss_type_latency_hist(RubyRequestType_NUM);
-
- std::vector<Histogram> miss_mach_latency_hist(MachineType_NUM);
- std::vector<std::vector<Histogram> >
- miss_type_mach_latency_hist(RubyRequestType_NUM,
- std::vector<Histogram>(MachineType_NUM));
-
- std::vector<Histogram> issue_to_initial_delay_hist(MachineType_NUM);
- std::vector<Histogram> initial_to_forward_delay_hist(MachineType_NUM);
- std::vector<Histogram>
- forward_to_first_response_delay_hist(MachineType_NUM);
- std::vector<Histogram>
- first_response_to_completion_delay_hist(MachineType_NUM);
- std::vector<uint64_t> incomplete_times(MachineType_NUM);
-
for (uint32_t i = 0; i < MachineType_NUM; i++) {
for (map<uint32_t, AbstractController*>::iterator it =
- g_abs_controls[i].begin();
- it != g_abs_controls[i].end(); ++it) {
+ g_abs_controls[i].begin();
+ it != g_abs_controls[i].end(); ++it) {
AbstractController *ctr = (*it).second;
Sequencer *seq = ctr->getSequencer();
if (seq != NULL) {
// add all the latencies
- latency_hist.add(seq->getLatencyHist());
- hit_latency_hist.add(seq->getHitLatencyHist());
- miss_latency_hist.add(seq->getMissLatencyHist());
+ m_latencyHist.add(seq->getLatencyHist());
+ m_hitLatencyHist.add(seq->getHitLatencyHist());
+ m_missLatencyHist.add(seq->getMissLatencyHist());
// add the per request type latencies
for (uint32_t j = 0; j < RubyRequestType_NUM; ++j) {
- type_latency_hist[j]
- .add(seq->getTypeLatencyHist(j));
- hit_type_latency_hist[j]
- .add(seq->getHitTypeLatencyHist(j));
- miss_type_latency_hist[j]
- .add(seq->getMissTypeLatencyHist(j));
+ m_typeLatencyHist[j]
+ ->add(seq->getTypeLatencyHist(j));
+ m_hitTypeLatencyHist[j]
+ ->add(seq->getHitTypeLatencyHist(j));
+ m_missTypeLatencyHist[j]
+ ->add(seq->getMissTypeLatencyHist(j));
}
// add the per machine type miss latencies
for (uint32_t j = 0; j < MachineType_NUM; ++j) {
- hit_mach_latency_hist[j]
- .add(seq->getHitMachLatencyHist(j));
- miss_mach_latency_hist[j]
- .add(seq->getMissMachLatencyHist(j));
+ m_hitMachLatencyHist[j]
+ ->add(seq->getHitMachLatencyHist(j));
+ m_missMachLatencyHist[j]
+ ->add(seq->getMissMachLatencyHist(j));
- issue_to_initial_delay_hist[j].add(
+ m_IssueToInitialDelayHist[j]->add(
seq->getIssueToInitialDelayHist(MachineType(j)));
- initial_to_forward_delay_hist[j].add(
+ m_InitialToForwardDelayHist[j]->add(
seq->getInitialToForwardDelayHist(MachineType(j)));
- forward_to_first_response_delay_hist[j].add(seq->
+ m_ForwardToFirstResponseDelayHist[j]->add(seq->
getForwardRequestToFirstResponseHist(MachineType(j)));
- first_response_to_completion_delay_hist[j].add(seq->
- getFirstResponseToCompletionDelayHist(MachineType(j)));
- incomplete_times[j] +=
+ m_FirstResponseToCompletionDelayHist[j]->add(seq->
+ getFirstResponseToCompletionDelayHist(
+ MachineType(j)));
+ m_IncompleteTimes[j] +=
seq->getIncompleteTimes(MachineType(j));
}
// add the per (request, machine) type miss latencies
for (uint32_t j = 0; j < RubyRequestType_NUM; j++) {
for (uint32_t k = 0; k < MachineType_NUM; k++) {
- hit_type_mach_latency_hist[j][k].add(
- seq->getHitTypeMachLatencyHist(j,k));
- miss_type_mach_latency_hist[j][k].add(
- seq->getMissTypeMachLatencyHist(j,k));
+ m_hitTypeMachLatencyHist[j][k]->add(
+ seq->getHitTypeMachLatencyHist(j,k));
+ m_missTypeMachLatencyHist[j][k]->add(
+ seq->getMissTypeMachLatencyHist(j,k));
}
}
}
}
}
-
- out << "latency: " << latency_hist << endl;
- for (int i = 0; i < RubyRequestType_NUM; i++) {
- if (type_latency_hist[i].size() > 0) {
- out << "latency: " << RubyRequestType(i) << ": "
- << type_latency_hist[i] << endl;
- }
- }
-
- out << "hit latency: " << hit_latency_hist << endl;
- for (int i = 0; i < RubyRequestType_NUM; i++) {
- if (hit_type_latency_hist[i].size() > 0) {
- out << "hit latency: " << RubyRequestType(i) << ": "
- << hit_type_latency_hist[i] << endl;
- }
- }
-
- for (int i = 0; i < MachineType_NUM; i++) {
- if (hit_mach_latency_hist[i].size() > 0) {
- out << "hit latency: " << MachineType(i) << ": "
- << hit_mach_latency_hist[i] << endl;
- }
- }
-
- for (int i = 0; i < RubyRequestType_NUM; i++) {
- for (int j = 0; j < MachineType_NUM; j++) {
- if (hit_type_mach_latency_hist[i][j].size() > 0) {
- out << "hit latency: " << RubyRequestType(i)
- << ": " << MachineType(j) << ": "
- << hit_type_mach_latency_hist[i][j] << endl;
- }
- }
- }
-
- out << "miss latency: " << miss_latency_hist << endl;
- for (int i = 0; i < RubyRequestType_NUM; i++) {
- if (miss_type_latency_hist[i].size() > 0) {
- out << "miss latency: " << RubyRequestType(i) << ": "
- << miss_type_latency_hist[i] << endl;
- }
- }
-
- for (int i = 0; i < MachineType_NUM; i++) {
- if (miss_mach_latency_hist[i].size() > 0) {
- out << "miss latency: " << MachineType(i) << ": "
- << miss_mach_latency_hist[i] << endl;
-
- out << "miss latency: " << MachineType(i)
- << "::issue_to_initial_request: "
- << issue_to_initial_delay_hist[i] << endl;
- out << "miss latency: " << MachineType(i)
- << "::initial_to_forward_request: "
- << initial_to_forward_delay_hist[i] << endl;
- out << "miss latency: " << MachineType(i)
- << "::forward_to_first_response: "
- << forward_to_first_response_delay_hist[i] << endl;
- out << "miss latency: " << MachineType(i)
- << "::first_response_to_completion: "
- << first_response_to_completion_delay_hist[i] << endl;
- out << "incomplete times: " << incomplete_times[i] << endl;
- }
- }
-
- for (int i = 0; i < RubyRequestType_NUM; i++) {
- for (int j = 0; j < MachineType_NUM; j++) {
- if (miss_type_mach_latency_hist[i][j].size() > 0) {
- out << "miss latency: " << RubyRequestType(i)
- << ": " << MachineType(j) << ": "
- << miss_type_mach_latency_hist[i][j] << endl;
- }
- }
- }
-
- out << endl;
-}
-
-void
-Profiler::printStats(ostream& out, bool short_stats)
-{
- out << endl;
- if (short_stats) {
- out << "SHORT ";
- }
- out << "Profiler Stats" << endl;
- out << "--------------" << endl;
-
- Cycles ruby_cycles = g_system_ptr->curCycle()-m_ruby_start;
-
- out << "Ruby_current_time: " << g_system_ptr->curCycle() << endl;
- out << "Ruby_start_time: " << m_ruby_start << endl;
- out << "Ruby_cycles: " << ruby_cycles << endl;
- out << endl;
-
- if (!short_stats) {
- out << "Busy Controller Counts:" << endl;
- for (uint32_t i = 0; i < MachineType_NUM; i++) {
- uint32_t size = MachineType_base_count((MachineType)i);
-
- for (uint32_t j = 0; j < size; j++) {
- MachineID machID;
- machID.type = (MachineType)i;
- machID.num = j;
-
- AbstractController *ctr =
- (*(g_abs_controls[i].find(j))).second;
- out << machID << ":" << ctr->getFullyBusyCycles() << " ";
- if ((j + 1) % 8 == 0) {
- out << endl;
- }
- }
- out << endl;
- }
- out << endl;
-
- out << "Busy Bank Count:" << m_busyBankCount << endl;
- out << endl;
-
- printOutstandingReqProfile(out);
- out << endl;
- }
-
- if (!short_stats) {
- out << "All Non-Zero Cycle Demand Cache Accesses" << endl;
- out << "----------------------------------------" << endl;
- printMissLatencyProfile(out);
-
- if (m_all_sharing_histogram.size() > 0) {
- out << "all_sharing: " << m_all_sharing_histogram << endl;
- out << "read_sharing: " << m_read_sharing_histogram << endl;
- out << "write_sharing: " << m_write_sharing_histogram << endl;
-
- out << "all_sharing_percent: ";
- m_all_sharing_histogram.printPercent(out);
- out << endl;
-
- out << "read_sharing_percent: ";
- m_read_sharing_histogram.printPercent(out);
- out << endl;
-
- out << "write_sharing_percent: ";
- m_write_sharing_histogram.printPercent(out);
- out << endl;
-
- int64 total_miss = m_cache_to_cache + m_memory_to_cache;
- out << "all_misses: " << total_miss << endl;
- out << "cache_to_cache_misses: " << m_cache_to_cache << endl;
- out << "memory_to_cache_misses: " << m_memory_to_cache << endl;
- out << "cache_to_cache_percent: "
- << 100.0 * (double(m_cache_to_cache) / double(total_miss))
- << endl;
- out << "memory_to_cache_percent: "
- << 100.0 * (double(m_memory_to_cache) / double(total_miss))
- << endl;
- out << endl;
- }
-
- printRequestProfile(out);
-
- if (!m_all_instructions) {
- m_address_profiler_ptr->printStats(out);
- }
-
- if (m_all_instructions) {
- m_inst_profiler_ptr->printStats(out);
- }
-
- out << endl;
- printDelayProfile(out);
- }
-}
-
-void
-Profiler::clearStats()
-{
- m_ruby_start = g_system_ptr->curCycle();
- m_real_time_start_time = time(NULL);
-
- m_busyBankCount = 0;
- m_read_sharing_histogram.clear();
- m_write_sharing_histogram.clear();
- m_all_sharing_histogram.clear();
- m_cache_to_cache = 0;
- m_memory_to_cache = 0;
-
- // update the start time
- m_ruby_start = g_system_ptr->curCycle();
}
void
msg.getType(), msg.getAccessMode(), id, false);
}
}
-
-void
-Profiler::profileSharing(const Address& addr, AccessType type,
- NodeID requestor, const Set& sharers,
- const Set& owner)
-{
- Set set_contacted(owner);
- if (type == AccessType_Write) {
- set_contacted.addSet(sharers);
- }
- set_contacted.remove(requestor);
- int number_contacted = set_contacted.count();
-
- if (type == AccessType_Write) {
- m_write_sharing_histogram.add(number_contacted);
- } else {
- m_read_sharing_histogram.add(number_contacted);
- }
- m_all_sharing_histogram.add(number_contacted);
-
- if (number_contacted == 0) {
- m_memory_to_cache++;
- } else {
- m_cache_to_cache++;
- }
-}
-
-void
-Profiler::bankBusy()
-{
- m_busyBankCount++;
-}
-
-void
-Profiler::rubyWatch(int id)
-{
- uint64 tr = 0;
- Address watch_address = Address(tr);
-
- DPRINTFN("%7s %3s RUBY WATCH %d\n", g_system_ptr->curCycle(), id,
- watch_address);
-
- // don't care about success or failure
- m_watch_address_set.insert(watch_address);
-}
-
-bool
-Profiler::watchAddress(Address addr)
-{
- return m_watch_address_set.count(addr) > 0;
-}
-
-Profiler *
-RubyProfilerParams::create()
-{
- return new Profiler(this);
-}
#ifndef __MEM_RUBY_PROFILER_PROFILER_HH__
#define __MEM_RUBY_PROFILER_PROFILER_HH__
-#include <iostream>
#include <map>
#include <string>
#include <vector>
+#include "base/callback.hh"
#include "base/hashmap.hh"
+#include "base/statistics.hh"
#include "mem/protocol/AccessType.hh"
#include "mem/protocol/PrefetchBit.hh"
#include "mem/protocol/RubyAccessMode.hh"
#include "mem/protocol/RubyRequestType.hh"
-#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/common/Histogram.hh"
-#include "mem/ruby/common/Set.hh"
#include "mem/ruby/system/MachineID.hh"
-#include "mem/ruby/system/MemoryControl.hh"
-#include "params/RubyProfiler.hh"
-#include "sim/sim_object.hh"
+#include "params/RubySystem.hh"
class RubyRequest;
class AddressProfiler;
-class Profiler : public SimObject
+class Profiler
{
public:
- typedef RubyProfilerParams Params;
- Profiler(const Params *);
+ Profiler(const RubySystemParams *);
~Profiler();
void wakeup();
-
- void setPeriodicStatsFile(const std::string& filename);
- void setPeriodicStatsInterval(int64_t period);
-
- void printStats(std::ostream& out, bool short_stats=false);
- void printShortStats(std::ostream& out) { printStats(out, true); }
- void printTraceStats(std::ostream& out) const;
- void clearStats();
- void printResourceUsage(std::ostream& out) const;
+ void regStats(const std::string &name);
+ void collateStats();
AddressProfiler* getAddressProfiler() { return m_address_profiler_ptr; }
AddressProfiler* getInstructionProfiler() { return m_inst_profiler_ptr; }
void addAddressTraceSample(const RubyRequest& msg, NodeID id);
- void profileRequest(const std::string& requestStr);
- void profileSharing(const Address& addr, AccessType type,
- NodeID requestor, const Set& sharers,
- const Set& owner);
-
- void profileMulticastRetry(const Address& addr, int count);
-
- void profileFilterAction(int action);
-
- void profileConflictingRequests(const Address& addr);
-
- void
- profileAverageLatencyEstimate(int latency)
- {
- m_average_latency_estimate.add(latency);
- }
-
- void controllerBusy(MachineID machID);
- void bankBusy();
-
- void print(std::ostream& out) const;
-
- void rubyWatch(int proc);
- bool watchAddress(Address addr);
-
- // return Ruby's start time
- Cycles getRubyStartTime() { return m_ruby_start; }
-
// added by SS
bool getHotLines() { return m_hot_lines; }
bool getAllInstructions() { return m_all_instructions; }
- private:
- void printRequestProfile(std::ostream &out) const;
- void printDelayProfile(std::ostream &out) const;
- void printOutstandingReqProfile(std::ostream &out) const;
- void printMissLatencyProfile(std::ostream &out) const;
-
private:
// Private copy constructor and assignment operator
Profiler(const Profiler& obj);
AddressProfiler* m_address_profiler_ptr;
AddressProfiler* m_inst_profiler_ptr;
- Cycles m_ruby_start;
- time_t m_real_time_start_time;
+ Stats::Histogram delayHistogram;
+ std::vector<Stats::Histogram *> delayVCHistogram;
+
+ //! Histogram for number of outstanding requests per cycle.
+ Stats::Histogram m_outstandReqHist;
+
+ //! Histogram for holding latency profile of all requests.
+ Stats::Histogram m_latencyHist;
+ std::vector<Stats::Histogram *> m_typeLatencyHist;
+
+ //! Histogram for holding latency profile of all requests that
+ //! hit in the controller connected to this sequencer.
+ Stats::Histogram m_hitLatencyHist;
+ std::vector<Stats::Histogram *> m_hitTypeLatencyHist;
- int64_t m_busyBankCount;
+ //! Histograms for profiling the latencies for requests that
+ //! did not required external messages.
+ std::vector<Stats::Histogram *> m_hitMachLatencyHist;
+ std::vector< std::vector<Stats::Histogram *> > m_hitTypeMachLatencyHist;
- Histogram m_read_sharing_histogram;
- Histogram m_write_sharing_histogram;
- Histogram m_all_sharing_histogram;
- int64 m_cache_to_cache;
- int64 m_memory_to_cache;
+ //! Histogram for holding latency profile of all requests that
+ //! miss in the controller connected to this sequencer.
+ Stats::Histogram m_missLatencyHist;
+ std::vector<Stats::Histogram *> m_missTypeLatencyHist;
- Histogram m_average_latency_estimate;
- m5::hash_set<Address> m_watch_address_set;
+ //! Histograms for profiling the latencies for requests that
+ //! required external messages.
+ std::vector<Stats::Histogram *> m_missMachLatencyHist;
+ std::vector< std::vector<Stats::Histogram *> > m_missTypeMachLatencyHist;
+
+ //! Histograms for recording the breakdown of miss latency
+ std::vector<Stats::Histogram *> m_IssueToInitialDelayHist;
+ std::vector<Stats::Histogram *> m_InitialToForwardDelayHist;
+ std::vector<Stats::Histogram *> m_ForwardToFirstResponseDelayHist;
+ std::vector<Stats::Histogram *> m_FirstResponseToCompletionDelayHist;
+ std::vector<Stats::Scalar> m_IncompleteTimes;
//added by SS
bool m_hot_lines;
bool m_all_instructions;
-
- int m_num_of_sequencers;
};
-inline std::ostream&
-operator<<(std::ostream& out, const Profiler& obj)
-{
- obj.print(out);
- out << std::flush;
- return out;
-}
-
#endif // __MEM_RUBY_PROFILER_PROFILER_HH__
+++ /dev/null
-# Copyright (c) 2009 Advanced Micro Devices, Inc.
-# 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.
-#
-# Authors: Steve Reinhardt
-# Brad Beckmann
-
-from m5.params import *
-from m5.SimObject import SimObject
-
-class RubyProfiler(SimObject):
- type = 'RubyProfiler'
- cxx_class = 'Profiler'
- cxx_header = "mem/ruby/profiler/Profiler.hh"
- hot_lines = Param.Bool(False, "")
- all_instructions = Param.Bool(False, "")
- num_of_sequencers = Param.Int("")
- ruby_system = Param.RubySystem("")
if env['PROTOCOL'] == 'None':
Return()
-SimObject('Profiler.py')
-
Source('AccessTraceForAddress.cc')
Source('AddressProfiler.cc')
Source('MemCntrlProfiler.cc')
#include "mem/ruby/system/System.hh"
AbstractController::AbstractController(const Params *p)
- : ClockedObject(p), Consumer(this), m_fully_busy_cycles(0),
- m_request_count(0)
+ : ClockedObject(p), Consumer(this)
{
m_version = p->version;
m_clusterID = p->cluster_id;
AbstractController::init()
{
params()->ruby_system->registerAbstractController(this);
+ m_delayHistogram.init(10);
+ uint32_t size = Network::getNumberOfVirtualNetworks();
+ for (uint32_t i = 0; i < size; i++) {
+ m_delayVCHistogram.push_back(new Stats::Histogram());
+ m_delayVCHistogram[i]->init(10);
+ }
}
void
-AbstractController::clearStats()
+AbstractController::resetStats()
{
- m_requestProfileMap.clear();
- m_request_count = 0;
-
- m_delayHistogram.clear();
-
+ m_delayHistogram.reset();
uint32_t size = Network::getNumberOfVirtualNetworks();
- m_delayVCHistogram.resize(size);
for (uint32_t i = 0; i < size; i++) {
- m_delayVCHistogram[i].clear();
- }
-
- Sequencer *seq = getSequencer();
- if (seq != NULL) {
- seq->clearStats();
+ m_delayVCHistogram[i]->reset();
}
}
void
-AbstractController::profileRequest(const std::string &request)
+AbstractController::regStats()
{
- m_request_count++;
-
- // if it doesn't exist, conveniently, it will be created with the
- // default value which is 0
- m_requestProfileMap[request]++;
+ m_fully_busy_cycles
+ .name(name() + ".fully_busy_cycles")
+ .desc("cycles for which number of transistions == max transitions")
+ .flags(Stats::nozero);
}
void
AbstractController::profileMsgDelay(uint32_t virtualNetwork, Cycles delay)
{
assert(virtualNetwork < m_delayVCHistogram.size());
- m_delayHistogram.add(delay);
- m_delayVCHistogram[virtualNetwork].add(delay);
+ m_delayHistogram.sample(delay);
+ m_delayVCHistogram[virtualNetwork]->sample(delay);
}
void
virtual void print(std::ostream & out) const = 0;
virtual void wakeup() = 0;
- virtual void clearStats() = 0;
- virtual void regStats() = 0;
+ virtual void resetStats() = 0;
+ virtual void regStats();
virtual void recordCacheTrace(int cntrl, CacheRecorder* tr) = 0;
virtual Sequencer* getSequencer() const = 0;
public:
MachineID getMachineID() const { return m_machineID; }
- uint64_t getFullyBusyCycles() const { return m_fully_busy_cycles; }
- uint64_t getRequestCount() const { return m_request_count; }
- const std::map<std::string, uint64_t>& getRequestProfileMap() const
- { return m_requestProfileMap; }
- Histogram& getDelayHist() { return m_delayHistogram; }
- Histogram& getDelayVCHist(uint32_t index)
- { return m_delayVCHistogram[index]; }
+ Stats::Histogram& getDelayHist() { return m_delayHistogram; }
+ Stats::Histogram& getDelayVCHist(uint32_t index)
+ { return *(m_delayVCHistogram[index]); }
MessageBuffer *getPeerQueue(uint32_t pid)
{
//! Counter for the number of cycles when the transitions carried out
//! were equal to the maximum allowed
- uint64_t m_fully_busy_cycles;
-
- //! Map for couting requests of different types. The controller should
- //! call requisite function for updating the count.
- std::map<std::string, uint64_t> m_requestProfileMap;
- uint64_t m_request_count;
+ Stats::Scalar m_fully_busy_cycles;
//! Histogram for profiling delay for the messages this controller
//! cares for
- Histogram m_delayHistogram;
- std::vector<Histogram> m_delayVCHistogram;
+ Stats::Histogram m_delayHistogram;
+ std::vector<Stats::Histogram *> m_delayVCHistogram;
//! Callback class used for collating statistics from all the
//! controller of this type.
public:
virtual ~StatsCallback() {}
-
- StatsCallback(AbstractController *_ctr)
- : ctr(_ctr)
- {
- }
-
+ StatsCallback(AbstractController *_ctr) : ctr(_ctr) {}
void process() {ctr->collateStats();}
};
};
// A pointer to the controller is needed for atomic support.
//
void setController(AbstractController* _cntrl) { m_controller = _cntrl; }
- int getId() { return m_version; }
+ uint32_t getId() { return m_version; }
unsigned int drain(DrainManager *dm);
protected:
void testDrainComplete();
void ruby_eviction_callback(const Address& address);
- int m_version;
+ uint32_t m_version;
AbstractController* m_controller;
MessageBuffer* m_mandatory_q_ptr;
PioPort pio_port;
block_size_bytes = Param.UInt32(64,
"default cache block size; must be a power of two");
mem_size = Param.MemorySize("total memory size of the system");
- stats_filename = Param.String("ruby.stats",
- "file to which ruby dumps its stats")
no_mem_vec = Param.Bool(False, "do not allocate Ruby's mem vector");
+
+ # Profiler related configuration variables
+ hot_lines = Param.Bool(False, "")
+ all_instructions = Param.Bool(False, "")
+ num_of_sequencers = Param.Int("")
}
Sequencer::Sequencer(const Params *p)
- : RubyPort(p), deadlockCheckEvent(this)
+ : RubyPort(p), m_IncompleteTimes(MachineType_NUM), deadlockCheckEvent(this)
{
- m_store_waiting_on_load_cycles = 0;
- m_store_waiting_on_store_cycles = 0;
- m_load_waiting_on_store_cycles = 0;
- m_load_waiting_on_load_cycles = 0;
-
m_outstanding_count = 0;
m_instCache_ptr = p->icache;
}
}
-void Sequencer::clearStats()
+void Sequencer::resetStats()
{
- m_outstandReqHist.clear();
-
- // Initialize the histograms that track latency of all requests
- m_latencyHist.clear(20);
- m_typeLatencyHist.resize(RubyRequestType_NUM);
- for (int i = 0; i < RubyRequestType_NUM; i++) {
- m_typeLatencyHist[i].clear(20);
- }
-
- // Initialize the histograms that track latency of requests that
- // hit in the cache attached to the sequencer.
- m_hitLatencyHist.clear(20);
- m_hitTypeLatencyHist.resize(RubyRequestType_NUM);
- m_hitTypeMachLatencyHist.resize(RubyRequestType_NUM);
-
+ m_latencyHist.reset();
+ m_hitLatencyHist.reset();
+ m_missLatencyHist.reset();
for (int i = 0; i < RubyRequestType_NUM; i++) {
- m_hitTypeLatencyHist[i].clear(20);
- m_hitTypeMachLatencyHist[i].resize(MachineType_NUM);
+ m_typeLatencyHist[i]->reset();
+ m_hitTypeLatencyHist[i]->reset();
+ m_missTypeLatencyHist[i]->reset();
for (int j = 0; j < MachineType_NUM; j++) {
- m_hitTypeMachLatencyHist[i][j].clear(20);
+ m_hitTypeMachLatencyHist[i][j]->reset();
+ m_missTypeMachLatencyHist[i][j]->reset();
}
}
- // Initialize the histograms that track the latency of requests that
- // missed in the cache attached to the sequencer.
- m_missLatencyHist.clear(20);
- m_missTypeLatencyHist.resize(RubyRequestType_NUM);
- m_missTypeMachLatencyHist.resize(RubyRequestType_NUM);
-
- for (int i = 0; i < RubyRequestType_NUM; i++) {
- m_missTypeLatencyHist[i].clear(20);
- m_missTypeMachLatencyHist[i].resize(MachineType_NUM);
- for (int j = 0; j < MachineType_NUM; j++) {
- m_missTypeMachLatencyHist[i][j].clear(20);
- }
- }
-
- m_hitMachLatencyHist.resize(MachineType_NUM);
- m_missMachLatencyHist.resize(MachineType_NUM);
- m_IssueToInitialDelayHist.resize(MachineType_NUM);
- m_InitialToForwardDelayHist.resize(MachineType_NUM);
- m_ForwardToFirstResponseDelayHist.resize(MachineType_NUM);
- m_FirstResponseToCompletionDelayHist.resize(MachineType_NUM);
- m_IncompleteTimes.resize(MachineType_NUM);
-
for (int i = 0; i < MachineType_NUM; i++) {
- m_missMachLatencyHist[i].clear(20);
- m_hitMachLatencyHist[i].clear(20);
+ m_missMachLatencyHist[i]->reset();
+ m_hitMachLatencyHist[i]->reset();
- m_IssueToInitialDelayHist[i].clear(20);
- m_InitialToForwardDelayHist[i].clear(20);
- m_ForwardToFirstResponseDelayHist[i].clear(20);
- m_FirstResponseToCompletionDelayHist[i].clear(20);
+ m_IssueToInitialDelayHist[i]->reset();
+ m_InitialToForwardDelayHist[i]->reset();
+ m_ForwardToFirstResponseDelayHist[i]->reset();
+ m_FirstResponseToCompletionDelayHist[i]->reset();
m_IncompleteTimes[i] = 0;
}
}
-void
-Sequencer::printStats(ostream & out) const
-{
- out << "Sequencer: " << m_name << endl
- << " store_waiting_on_load_cycles: "
- << m_store_waiting_on_load_cycles << endl
- << " store_waiting_on_store_cycles: "
- << m_store_waiting_on_store_cycles << endl
- << " load_waiting_on_load_cycles: "
- << m_load_waiting_on_load_cycles << endl
- << " load_waiting_on_store_cycles: "
- << m_load_waiting_on_store_cycles << endl;
-}
-
void
Sequencer::printProgress(ostream& out) const
{
// Check if there is any outstanding read request for the same
// cache line.
if (m_readRequestTable.count(line_addr) > 0) {
- m_store_waiting_on_load_cycles++;
+ m_store_waiting_on_load++;
return RequestStatus_Aliased;
}
m_outstanding_count++;
} else {
// There is an outstanding write request for the cache line
- m_store_waiting_on_store_cycles++;
+ m_store_waiting_on_store++;
return RequestStatus_Aliased;
}
} else {
// Check if there is any outstanding write request for the same
// cache line.
if (m_writeRequestTable.count(line_addr) > 0) {
- m_load_waiting_on_store_cycles++;
+ m_load_waiting_on_store++;
return RequestStatus_Aliased;
}
m_outstanding_count++;
} else {
// There is an outstanding read request for the cache line
- m_load_waiting_on_load_cycles++;
+ m_load_waiting_on_load++;
return RequestStatus_Aliased;
}
}
- m_outstandReqHist.add(m_outstanding_count);
+ m_outstandReqHist.sample(m_outstanding_count);
assert(m_outstanding_count ==
(m_writeRequestTable.size() + m_readRequestTable.size()));
Cycles forwardRequestTime,
Cycles firstResponseTime, Cycles completionTime)
{
- m_latencyHist.add(cycles);
- m_typeLatencyHist[type].add(cycles);
+ m_latencyHist.sample(cycles);
+ m_typeLatencyHist[type]->sample(cycles);
if (isExternalHit) {
- m_missLatencyHist.add(cycles);
- m_missTypeLatencyHist[type].add(cycles);
+ m_missLatencyHist.sample(cycles);
+ m_missTypeLatencyHist[type]->sample(cycles);
if (respondingMach != MachineType_NUM) {
- m_missMachLatencyHist[respondingMach].add(cycles);
- m_missTypeMachLatencyHist[type][respondingMach].add(cycles);
+ m_missMachLatencyHist[respondingMach]->sample(cycles);
+ m_missTypeMachLatencyHist[type][respondingMach]->sample(cycles);
if ((issuedTime <= initialRequestTime) &&
(initialRequestTime <= forwardRequestTime) &&
(forwardRequestTime <= firstResponseTime) &&
(firstResponseTime <= completionTime)) {
- m_IssueToInitialDelayHist[respondingMach].add(
+ m_IssueToInitialDelayHist[respondingMach]->sample(
initialRequestTime - issuedTime);
- m_InitialToForwardDelayHist[respondingMach].add(
+ m_InitialToForwardDelayHist[respondingMach]->sample(
forwardRequestTime - initialRequestTime);
- m_ForwardToFirstResponseDelayHist[respondingMach].add(
+ m_ForwardToFirstResponseDelayHist[respondingMach]->sample(
firstResponseTime - forwardRequestTime);
- m_FirstResponseToCompletionDelayHist[respondingMach].add(
+ m_FirstResponseToCompletionDelayHist[respondingMach]->sample(
completionTime - firstResponseTime);
} else {
m_IncompleteTimes[respondingMach]++;
}
}
} else {
- m_hitLatencyHist.add(cycles);
- m_hitTypeLatencyHist[type].add(cycles);
+ m_hitLatencyHist.sample(cycles);
+ m_hitTypeLatencyHist[type]->sample(cycles);
if (respondingMach != MachineType_NUM) {
- m_hitMachLatencyHist[respondingMach].add(cycles);
- m_hitTypeMachLatencyHist[type][respondingMach].add(cycles);
+ m_hitMachLatencyHist[respondingMach]->sample(cycles);
+ m_hitTypeMachLatencyHist[type][respondingMach]->sample(cycles);
}
}
}
{
ruby_eviction_callback(address);
}
+
+void
+Sequencer::regStats()
+{
+ m_store_waiting_on_load
+ .name(name() + ".store_waiting_on_load")
+ .desc("Number of times a store aliased with a pending load")
+ .flags(Stats::nozero);
+ m_store_waiting_on_store
+ .name(name() + ".store_waiting_on_store")
+ .desc("Number of times a store aliased with a pending store")
+ .flags(Stats::nozero);
+ m_load_waiting_on_load
+ .name(name() + ".load_waiting_on_load")
+ .desc("Number of times a load aliased with a pending load")
+ .flags(Stats::nozero);
+ m_load_waiting_on_store
+ .name(name() + ".load_waiting_on_store")
+ .desc("Number of times a load aliased with a pending store")
+ .flags(Stats::nozero);
+
+ // These statistical variables are not for display.
+ // The profiler will collate these across different
+ // sequencers and display those collated statistics.
+ m_outstandReqHist.init(10);
+ m_latencyHist.init(10);
+ m_hitLatencyHist.init(10);
+ m_missLatencyHist.init(10);
+
+ for (int i = 0; i < RubyRequestType_NUM; i++) {
+ m_typeLatencyHist.push_back(new Stats::Histogram());
+ m_typeLatencyHist[i]->init(10);
+
+ m_hitTypeLatencyHist.push_back(new Stats::Histogram());
+ m_hitTypeLatencyHist[i]->init(10);
+
+ m_missTypeLatencyHist.push_back(new Stats::Histogram());
+ m_missTypeLatencyHist[i]->init(10);
+ }
+
+ for (int i = 0; i < MachineType_NUM; i++) {
+ m_hitMachLatencyHist.push_back(new Stats::Histogram());
+ m_hitMachLatencyHist[i]->init(10);
+
+ m_missMachLatencyHist.push_back(new Stats::Histogram());
+ m_missMachLatencyHist[i]->init(10);
+
+ m_IssueToInitialDelayHist.push_back(new Stats::Histogram());
+ m_IssueToInitialDelayHist[i]->init(10);
+
+ m_InitialToForwardDelayHist.push_back(new Stats::Histogram());
+ m_InitialToForwardDelayHist[i]->init(10);
+
+ m_ForwardToFirstResponseDelayHist.push_back(new Stats::Histogram());
+ m_ForwardToFirstResponseDelayHist[i]->init(10);
+
+ m_FirstResponseToCompletionDelayHist.push_back(new Stats::Histogram());
+ m_FirstResponseToCompletionDelayHist[i]->init(10);
+ }
+
+ for (int i = 0; i < RubyRequestType_NUM; i++) {
+ m_hitTypeMachLatencyHist.push_back(std::vector<Stats::Histogram *>());
+ m_missTypeMachLatencyHist.push_back(std::vector<Stats::Histogram *>());
+
+ for (int j = 0; j < MachineType_NUM; j++) {
+ m_hitTypeMachLatencyHist[i].push_back(new Stats::Histogram());
+ m_hitTypeMachLatencyHist[i][j]->init(10);
+
+ m_missTypeMachLatencyHist[i].push_back(new Stats::Histogram());
+ m_missTypeMachLatencyHist[i][j]->init(10);
+ }
+ }
+}
// Public Methods
void wakeup(); // Used only for deadlock detection
void printProgress(std::ostream& out) const;
- void clearStats();
+ void resetStats();
+ void collateStats();
+ void regStats();
void writeCallback(const Address& address,
DataBlock& data,
{ deschedule(deadlockCheckEvent); }
void print(std::ostream& out) const;
- void printStats(std::ostream& out) const;
void checkCoherence(const Address& address);
void markRemoved();
void invalidateSC(const Address& address);
void recordRequestType(SequencerRequestType requestType);
- Histogram& getOutstandReqHist() { return m_outstandReqHist; }
+ Stats::Histogram& getOutstandReqHist() { return m_outstandReqHist; }
- Histogram& getLatencyHist() { return m_latencyHist; }
- Histogram& getTypeLatencyHist(uint32_t t)
- { return m_typeLatencyHist[t]; }
+ Stats::Histogram& getLatencyHist() { return m_latencyHist; }
+ Stats::Histogram& getTypeLatencyHist(uint32_t t)
+ { return *m_typeLatencyHist[t]; }
- Histogram& getHitLatencyHist() { return m_hitLatencyHist; }
- Histogram& getHitTypeLatencyHist(uint32_t t)
- { return m_hitTypeLatencyHist[t]; }
+ Stats::Histogram& getHitLatencyHist() { return m_hitLatencyHist; }
+ Stats::Histogram& getHitTypeLatencyHist(uint32_t t)
+ { return *m_hitTypeLatencyHist[t]; }
- Histogram& getHitMachLatencyHist(uint32_t t)
- { return m_hitMachLatencyHist[t]; }
+ Stats::Histogram& getHitMachLatencyHist(uint32_t t)
+ { return *m_hitMachLatencyHist[t]; }
- Histogram& getHitTypeMachLatencyHist(uint32_t r, uint32_t t)
- { return m_hitTypeMachLatencyHist[r][t]; }
+ Stats::Histogram& getHitTypeMachLatencyHist(uint32_t r, uint32_t t)
+ { return *m_hitTypeMachLatencyHist[r][t]; }
- Histogram& getMissLatencyHist() { return m_missLatencyHist; }
- Histogram& getMissTypeLatencyHist(uint32_t t)
- { return m_missTypeLatencyHist[t]; }
+ Stats::Histogram& getMissLatencyHist()
+ { return m_missLatencyHist; }
+ Stats::Histogram& getMissTypeLatencyHist(uint32_t t)
+ { return *m_missTypeLatencyHist[t]; }
- Histogram& getMissMachLatencyHist(uint32_t t)
- { return m_missMachLatencyHist[t]; }
+ Stats::Histogram& getMissMachLatencyHist(uint32_t t) const
+ { return *m_missMachLatencyHist[t]; }
- Histogram& getMissTypeMachLatencyHist(uint32_t r, uint32_t t)
- { return m_missTypeMachLatencyHist[r][t]; }
+ Stats::Histogram&
+ getMissTypeMachLatencyHist(uint32_t r, uint32_t t) const
+ { return *m_missTypeMachLatencyHist[r][t]; }
- Histogram& getIssueToInitialDelayHist(uint32_t t)
- { return m_IssueToInitialDelayHist[t]; }
+ Stats::Histogram& getIssueToInitialDelayHist(uint32_t t) const
+ { return *m_IssueToInitialDelayHist[t]; }
- Histogram& getInitialToForwardDelayHist(const MachineType t)
- { return m_InitialToForwardDelayHist[t]; }
+ Stats::Histogram&
+ getInitialToForwardDelayHist(const MachineType t) const
+ { return *m_InitialToForwardDelayHist[t]; }
- Histogram& getForwardRequestToFirstResponseHist(const MachineType t)
- { return m_ForwardToFirstResponseDelayHist[t]; }
+ Stats::Histogram&
+ getForwardRequestToFirstResponseHist(const MachineType t) const
+ { return *m_ForwardToFirstResponseDelayHist[t]; }
- Histogram& getFirstResponseToCompletionDelayHist(const MachineType t)
- { return m_FirstResponseToCompletionDelayHist[t]; }
+ Stats::Histogram&
+ getFirstResponseToCompletionDelayHist(const MachineType t) const
+ { return *m_FirstResponseToCompletionDelayHist[t]; }
- const uint64_t getIncompleteTimes(const MachineType t) const
+ Stats::Counter getIncompleteTimes(const MachineType t) const
{ return m_IncompleteTimes[t]; }
private:
int m_outstanding_count;
bool m_deadlock_check_scheduled;
- uint32_t m_store_waiting_on_load_cycles;
- uint32_t m_store_waiting_on_store_cycles;
- uint32_t m_load_waiting_on_store_cycles;
- uint32_t m_load_waiting_on_load_cycles;
+ //! Counters for recording aliasing information.
+ Stats::Scalar m_store_waiting_on_load;
+ Stats::Scalar m_store_waiting_on_store;
+ Stats::Scalar m_load_waiting_on_store;
+ Stats::Scalar m_load_waiting_on_load;
bool m_usingNetworkTester;
//! Histogram for number of outstanding requests per cycle.
- Histogram m_outstandReqHist;
+ Stats::Histogram m_outstandReqHist;
//! Histogram for holding latency profile of all requests.
- Histogram m_latencyHist;
- std::vector<Histogram> m_typeLatencyHist;
+ Stats::Histogram m_latencyHist;
+ std::vector<Stats::Histogram *> m_typeLatencyHist;
//! Histogram for holding latency profile of all requests that
//! hit in the controller connected to this sequencer.
- Histogram m_hitLatencyHist;
- std::vector<Histogram> m_hitTypeLatencyHist;
+ Stats::Histogram m_hitLatencyHist;
+ std::vector<Stats::Histogram *> m_hitTypeLatencyHist;
//! Histograms for profiling the latencies for requests that
//! did not required external messages.
- std::vector<Histogram> m_hitMachLatencyHist;
- std::vector< std::vector<Histogram> > m_hitTypeMachLatencyHist;
+ std::vector<Stats::Histogram *> m_hitMachLatencyHist;
+ std::vector< std::vector<Stats::Histogram *> > m_hitTypeMachLatencyHist;
//! Histogram for holding latency profile of all requests that
//! miss in the controller connected to this sequencer.
- Histogram m_missLatencyHist;
- std::vector<Histogram> m_missTypeLatencyHist;
+ Stats::Histogram m_missLatencyHist;
+ std::vector<Stats::Histogram *> m_missTypeLatencyHist;
//! Histograms for profiling the latencies for requests that
//! required external messages.
- std::vector<Histogram> m_missMachLatencyHist;
- std::vector< std::vector<Histogram> > m_missTypeMachLatencyHist;
+ std::vector<Stats::Histogram *> m_missMachLatencyHist;
+ std::vector< std::vector<Stats::Histogram *> > m_missTypeMachLatencyHist;
//! Histograms for recording the breakdown of miss latency
- std::vector<Histogram> m_IssueToInitialDelayHist;
- std::vector<Histogram> m_InitialToForwardDelayHist;
- std::vector<Histogram> m_ForwardToFirstResponseDelayHist;
- std::vector<Histogram> m_FirstResponseToCompletionDelayHist;
- std::vector<uint64_t> m_IncompleteTimes;
+ std::vector<Stats::Histogram *> m_IssueToInitialDelayHist;
+ std::vector<Stats::Histogram *> m_InitialToForwardDelayHist;
+ std::vector<Stats::Histogram *> m_ForwardToFirstResponseDelayHist;
+ std::vector<Stats::Histogram *> m_FirstResponseToCompletionDelayHist;
+ std::vector<Stats::Counter> m_IncompleteTimes;
class SequencerWakeupEvent : public Event
#include "debug/RubySystem.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/network/Network.hh"
-#include "mem/ruby/profiler/Profiler.hh"
#include "mem/ruby/system/System.hh"
#include "sim/eventq.hh"
#include "sim/simulate.hh"
}
if (p->no_mem_vec) {
- m_mem_vec_ptr = NULL;
+ m_mem_vec = NULL;
} else {
- m_mem_vec_ptr = new MemoryVector;
- m_mem_vec_ptr->resize(m_memory_size_bytes);
+ m_mem_vec = new MemoryVector;
+ m_mem_vec->resize(m_memory_size_bytes);
}
- // Print ruby configuration and stats at exit and when asked for
- Stats::registerDumpCallback(new RubyDumpStatsCallback(p->stats_filename,
- this));
-
m_warmup_enabled = false;
m_cooldown_enabled = false;
// Resize to the size of different machine types
g_abs_controls.resize(MachineType_NUM);
-}
-void
-RubySystem::registerNetwork(Network* network_ptr)
-{
- m_network_ptr = network_ptr;
+ // Collate the statistics before they are printed.
+ Stats::registerDumpCallback(new RubyStatsCallback(this));
+ // Create the profiler
+ m_profiler = new Profiler(p);
}
void
-RubySystem::registerProfiler(Profiler* profiler_ptr)
+RubySystem::registerNetwork(Network* network_ptr)
{
- m_profiler_ptr = profiler_ptr;
+ m_network = network_ptr;
}
void
RubySystem::~RubySystem()
{
- delete m_network_ptr;
- delete m_profiler_ptr;
- if (m_mem_vec_ptr)
- delete m_mem_vec_ptr;
-}
-
-void
-RubySystem::printStats(ostream& out)
-{
- m_profiler_ptr->printStats(out);
+ delete m_network;
+ delete m_profiler;
+ if (m_mem_vec)
+ delete m_mem_vec;
}
void
uint8_t *raw_data = NULL;
- if (m_mem_vec_ptr != NULL) {
- uint64 memory_trace_size = m_mem_vec_ptr->collatePages(raw_data);
+ if (m_mem_vec != NULL) {
+ uint64 memory_trace_size = m_mem_vec->collatePages(raw_data);
string memory_trace_file = name() + ".memory.gz";
writeCompressedTrace(raw_data, memory_trace_file,
{
uint8_t *uncompressed_trace = NULL;
- if (m_mem_vec_ptr != NULL) {
+ if (m_mem_vec != NULL) {
string memory_trace_file;
uint64 memory_trace_size = 0;
readCompressedTrace(memory_trace_file, uncompressed_trace,
memory_trace_size);
- m_mem_vec_ptr->populatePages(uncompressed_trace);
+ m_mem_vec->populatePages(uncompressed_trace);
delete [] uncompressed_trace;
uncompressed_trace = NULL;
void
RubySystem::resetStats()
{
- m_profiler_ptr->clearStats();
- for (uint32_t cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) {
- m_abs_cntrl_vec[cntrl]->clearStats();
- }
-
g_ruby_start = curCycle();
}
m_memory_controller_vec[i]->functionalWriteBuffers(pkt);
}
- num_functional_writes += m_network_ptr->functionalWrite(pkt);
+ num_functional_writes += m_network->functionalWrite(pkt);
DPRINTF(RubySystem, "Messages written = %u\n", num_functional_writes);
return true;
{
return new RubySystem(this);
}
-
-/**
- * virtual process function that is invoked when the callback
- * queue is executed.
- */
-void
-RubyDumpStatsCallback::process()
-{
- ruby_system->printStats(*os);
-}
#include "base/output.hh"
#include "mem/packet.hh"
#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/profiler/Profiler.hh"
#include "mem/ruby/recorder/CacheRecorder.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh"
+#include "mem/ruby/system/MemoryControl.hh"
#include "mem/ruby/system/MemoryVector.hh"
#include "mem/ruby/system/SparseMemory.hh"
#include "params/RubySystem.hh"
#include "sim/clocked_object.hh"
class Network;
-class Profiler;
-class MemoryControl;
class RubySystem : public ClockedObject
{
Network*
getNetwork()
{
- assert(m_network_ptr != NULL);
- return m_network_ptr;
+ assert(m_network != NULL);
+ return m_network;
}
Profiler*
getProfiler()
{
- assert(m_profiler_ptr != NULL);
- return m_profiler_ptr;
+ assert(m_profiler != NULL);
+ return m_profiler;
}
MemoryVector*
getMemoryVector()
{
- assert(m_mem_vec_ptr != NULL);
- return m_mem_vec_ptr;
+ assert(m_mem_vec != NULL);
+ return m_mem_vec;
}
- void printStats(std::ostream& out);
+ void regStats() { m_profiler->regStats(name()); }
+ void collateStats() { m_profiler->collateStats(); }
void resetStats();
- void print(std::ostream& out) const;
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string §ion);
bool functionalWrite(Packet *ptr);
void registerNetwork(Network*);
- void registerProfiler(Profiler*);
void registerAbstractController(AbstractController*);
void registerSparseMemory(SparseMemory*);
void registerMemController(MemoryControl *mc);
static uint64_t m_memory_size_bytes;
static uint32_t m_memory_size_bits;
- Network* m_network_ptr;
+ Network* m_network;
std::vector<MemoryControl *> m_memory_controller_vec;
std::vector<AbstractController *> m_abs_cntrl_vec;
public:
- Profiler* m_profiler_ptr;
- MemoryVector* m_mem_vec_ptr;
+ Profiler* m_profiler;
+ MemoryVector* m_mem_vec;
bool m_warmup_enabled;
bool m_cooldown_enabled;
CacheRecorder* m_cache_recorder;
std::vector<SparseMemory*> m_sparse_memory_vector;
};
-inline std::ostream&
-operator<<(std::ostream& out, const RubySystem& obj)
-{
- //obj.print(out);
- out << std::flush;
- return out;
-}
-
-class RubyDumpStatsCallback : public Callback
+class RubyStatsCallback : public Callback
{
private:
- std::ostream *os;
RubySystem *ruby_system;
public:
- virtual ~RubyDumpStatsCallback() {}
-
- RubyDumpStatsCallback(const std::string& _stats_filename,
- RubySystem *system)
- {
- os = simout.create(_stats_filename);
- ruby_system = system;
- }
-
- void process();
+ virtual ~RubyStatsCallback() {}
+ RubyStatsCallback(RubySystem *system) : ruby_system(system) {}
+ void process() { ruby_system->collateStats(); }
};
#endif // __MEM_RUBY_SYSTEM_SYSTEM_HH__
{
}
-void
-WireBuffer::clearStats() const
-{
-}
-
-void
-WireBuffer::printStats(ostream& out) const
-{
-}
-
void
WireBuffer::wakeup()
{
bool areNSlotsAvailable(int n) { return true; }; // infinite queue length
void print(std::ostream& out) const;
- void clearStats() const;
- void printStats(std::ostream& out) const;
-
uint64_t m_msg_counter;
private:
void print(std::ostream& out) const;
void wakeup();
- void clearStats();
+ void resetStats();
void regStats();
void collateStats();
code.dedent()
code('''
AbstractController::init();
- clearStats();
+ resetStats();
}
''')
void
$c_ident::regStats()
{
+ AbstractController::regStats();
+
if (m_version == 0) {
for (${ident}_Event event = ${ident}_Event_FIRST;
event < ${ident}_Event_NUM; ++event) {
Stats::Vector *t = new Stats::Vector();
t->init(m_num_controllers);
- t->name(name() + "." + ${ident}_Event_to_string(event));
+ t->name(g_system_ptr->name() + ".${c_ident}." +
+ ${ident}_Event_to_string(event));
t->flags(Stats::pdf | Stats::total | Stats::oneline |
Stats::nozero);
Stats::Vector *t = new Stats::Vector();
t->init(m_num_controllers);
- t->name(name() + "." + ${ident}_State_to_string(state) +
+ t->name(g_system_ptr->name() + ".${c_ident}." +
+ ${ident}_State_to_string(state) +
"." + ${ident}_Event_to_string(event));
t->flags(Stats::pdf | Stats::total | Stats::oneline |
out << "[$c_ident " << m_version << "]";
}
-void $c_ident::clearStats()
+void $c_ident::resetStats()
{
for (int state = 0; state < ${ident}_State_NUM; state++) {
for (int event = 0; event < ${ident}_Event_NUM; event++) {
m_event_counters[event] = 0;
}
- AbstractController::clearStats();
+ AbstractController::resetStats();
}
''')