ruby: reset and dump stats along with reset of the system
[gem5.git] / src / mem / ruby / profiler / Profiler.cc
index a42d919f76dfd62e15123ce19a08e133cc71f4c6..9f5fb4fd9b22588476e2be105ec91fc4ec9b510b 100644 (file)
 // Allows use of times() library call, which determines virtual runtime
 #include <sys/resource.h>
 #include <sys/times.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 #include <algorithm>
+#include <fstream>
 
 #include "base/stl_helpers.hh"
 #include "base/str.hh"
-#include "mem/protocol/CacheMsg.hh"
 #include "mem/protocol/MachineType.hh"
-#include "mem/protocol/Protocol.hh"
-#include "mem/ruby/common/Debug.hh"
+#include "mem/protocol/RubyRequest.hh"
 #include "mem/ruby/network/Network.hh"
 #include "mem/ruby/profiler/AddressProfiler.hh"
 #include "mem/ruby/profiler/Profiler.hh"
 #include "mem/ruby/system/System.hh"
-#include "mem/ruby/system/System.hh"
 
 using namespace std;
 using m5::stl_helpers::operator<<;
 
-extern ostream* debug_cout_ptr;
-
 static double process_memory_total();
 static double process_memory_resident();
 
 Profiler::Profiler(const Params *p)
-    : SimObject(p)
+    : SimObject(p), m_event(this)
 {
     m_inst_profiler_ptr = NULL;
     m_address_profiler_ptr = NULL;
@@ -95,6 +93,8 @@ Profiler::Profiler(const Params *p)
         m_inst_profiler_ptr->setHotLines(m_hot_lines);
         m_inst_profiler_ptr->setAllInstructions(m_all_instructions);
     }
+
+    p->ruby_system->registerProfiler(this);
 }
 
 Profiler::~Profiler()
@@ -109,17 +109,17 @@ Profiler::wakeup()
 {
     // FIXME - avoid the repeated code
 
-    vector<integer_t> perProcCycleCount(m_num_of_sequencers);
+    vector<int64_t> perProcCycleCount(m_num_of_sequencers);
 
     for (int i = 0; i < m_num_of_sequencers; i++) {
         perProcCycleCount[i] =
-            g_system_ptr->getCycleCount(i) - m_cycles_executed_at_start[i] + 1;
+            g_system_ptr->getTime() - m_cycles_executed_at_start[i] + 1;
         // The +1 allows us to avoid division by zero
     }
 
     ostream &out = *m_periodic_output_file_ptr;
 
-    out << "ruby_cycles: " << g_eventQueue_ptr->getTime()-m_ruby_start << endl
+    out << "ruby_cycles: " << g_system_ptr->getTime()-m_ruby_start << endl
         << "mbytes_resident: " << process_memory_resident() << endl
         << "mbytes_total: " << process_memory_total() << endl;
 
@@ -137,7 +137,7 @@ Profiler::wakeup()
     }
 
     //g_system_ptr->getNetwork()->printStats(out);
-    g_eventQueue_ptr->scheduleEvent(this, m_stats_period);
+    schedule(m_event, g_system_ptr->clockEdge(Cycles(m_stats_period )));
 }
 
 void
@@ -151,26 +151,17 @@ Profiler::setPeriodicStatsFile(const string& filename)
     }
 
     m_periodic_output_file_ptr = new ofstream(filename.c_str());
-    g_eventQueue_ptr->scheduleEvent(this, 1);
+    schedule(m_event, g_system_ptr->clockEdge(Cycles(1)));
 }
 
 void
-Profiler::setPeriodicStatsInterval(integer_t period)
+Profiler::setPeriodicStatsInterval(int64_t period)
 {
     cout << "Recording periodic statistics every " << m_stats_period
          << " Ruby cycles" << endl;
 
     m_stats_period = period;
-    g_eventQueue_ptr->scheduleEvent(this, 1);
-}
-
-void
-Profiler::printConfig(ostream& out) const
-{
-    out << endl;
-    out << "Profiler Configuration" << endl;
-    out << "----------------------" << endl;
-    out << "periodic_stats_period: " << m_stats_period << endl;
+    schedule(m_event, g_system_ptr->clockEdge(Cycles(1)));
 }
 
 void
@@ -194,7 +185,7 @@ Profiler::printStats(ostream& out, bool short_stats)
     double minutes = seconds / 60.0;
     double hours = minutes / 60.0;
     double days = hours / 24.0;
-    Time ruby_cycles = g_eventQueue_ptr->getTime()-m_ruby_start;
+    Time ruby_cycles = g_system_ptr->getTime()-m_ruby_start;
 
     if (!short_stats) {
         out << "Elapsed_time_in_seconds: " << seconds << endl;
@@ -217,7 +208,7 @@ Profiler::printStats(ostream& out, bool short_stats)
     out << "Virtual_time_in_days:    " << days << endl;
     out << endl;
 
-    out << "Ruby_current_time: " << g_eventQueue_ptr->getTime() << endl;
+    out << "Ruby_current_time: " << g_system_ptr->getTime() << endl;
     out << "Ruby_start_time: " << m_ruby_start << endl;
     out << "Ruby_cycles: " << ruby_cycles << endl;
     out << endl;
@@ -232,11 +223,11 @@ Profiler::printStats(ostream& out, bool short_stats)
         out << endl;
     }
 
-    vector<integer_t> perProcCycleCount(m_num_of_sequencers);
+    vector<int64_t> perProcCycleCount(m_num_of_sequencers);
 
     for (int i = 0; i < m_num_of_sequencers; i++) {
         perProcCycleCount[i] =
-            g_system_ptr->getCycleCount(i) - m_cycles_executed_at_start[i] + 1;
+            g_system_ptr->getTime() - m_cycles_executed_at_start[i] + 1;
         // The +1 allows us to avoid division by zero
     }
 
@@ -322,7 +313,7 @@ Profiler::printStats(ostream& out, bool short_stats)
         out << "prefetch_latency: " << m_allSWPrefetchLatencyHistogram << endl;
         for (int i = 0; i < m_SWPrefetchLatencyHistograms.size(); i++) {
             if (m_SWPrefetchLatencyHistograms[i].size() > 0) {
-                out << "prefetch_latency_" << CacheRequestType(i) << ": "
+                out << "prefetch_latency_" << RubyRequestType(i) << ": "
                     << m_SWPrefetchLatencyHistograms[i] << endl;
             }
         }
@@ -428,7 +419,7 @@ Profiler::printResourceUsage(ostream& out) const
     out << "Resource Usage" << endl;
     out << "--------------" << endl;
 
-    integer_t pagesize = getpagesize(); // page size in bytes
+    int64_t pagesize = getpagesize(); // page size in bytes
     out << "page_size: " << pagesize << endl;
 
     rusage usage;
@@ -446,14 +437,15 @@ Profiler::printResourceUsage(ostream& out) const
 void
 Profiler::clearStats()
 {
-    m_ruby_start = g_eventQueue_ptr->getTime();
+    m_ruby_start = g_system_ptr->getTime();
+    m_real_time_start_time = time(NULL);
 
     m_cycles_executed_at_start.resize(m_num_of_sequencers);
     for (int i = 0; i < m_num_of_sequencers; i++) {
         if (g_system_ptr == NULL) {
             m_cycles_executed_at_start[i] = 0;
         } else {
-            m_cycles_executed_at_start[i] = g_system_ptr->getCycleCount(i);
+            m_cycles_executed_at_start[i] = g_system_ptr->getTime();
         }
     }
 
@@ -469,7 +461,7 @@ Profiler::clearStats()
 
     m_delayedCyclesHistogram.clear();
     m_delayedCyclesNonPFHistogram.clear();
-    int size = RubySystem::getNetwork()->getNumberOfVirtualNetworks();
+    int size = Network::getNumberOfVirtualNetworks();
     m_delayedCyclesVCHistograms.resize(size);
     for (int i = 0; i < size; i++) {
         m_delayedCyclesVCHistograms[i].clear();
@@ -502,7 +494,7 @@ Profiler::clearStats()
     m_dirFirstResponseToCompleteHistogram.clear(200);
     m_dirIncompleteTimes = 0;
 
-    m_SWPrefetchLatencyHistograms.resize(CacheRequestType_NUM);
+    m_SWPrefetchLatencyHistograms.resize(RubyRequestType_NUM);
     for (int i = 0; i < m_SWPrefetchLatencyHistograms.size(); i++) {
         m_SWPrefetchLatencyHistograms[i].clear(200);
     }
@@ -533,13 +525,13 @@ Profiler::clearStats()
     //g_eventQueue_ptr->triggerAllEvents();
 
     // update the start time
-    m_ruby_start = g_eventQueue_ptr->getTime();
+    m_ruby_start = g_system_ptr->getTime();
 }
 
 void
-Profiler::addAddressTraceSample(const CacheMsg& msg, NodeID id)
+Profiler::addAddressTraceSample(const RubyRequest& msg, NodeID id)
 {
-    if (msg.getType() != CacheRequestType_IFETCH) {
+    if (msg.getType() != RubyRequestType_IFETCH) {
         // Note: The following line should be commented out if you
         // want to use the special profiling that is part of the GS320
         // protocol
@@ -685,7 +677,7 @@ Profiler::missLatencyDir(Time issuedTime,
 // non-zero cycle prefetch request
 void
 Profiler::swPrefetchLatency(Time cycles, 
-                            CacheRequestType type,
+                            RubyRequestType type,
                             const GenericMachineType respondingMach)
 {
     m_allSWPrefetchLatencyHistogram.add(cycles);
@@ -697,39 +689,6 @@ Profiler::swPrefetchLatency(Time cycles,
     }
 }
 
-void
-Profiler::profileTransition(const string& component, NodeID version,
-    Address addr, const string& state, const string& event,
-    const string& next_state, const string& note)
-{
-    const int EVENT_SPACES = 20;
-    const int ID_SPACES = 3;
-    const int TIME_SPACES = 7;
-    const int COMP_SPACES = 10;
-    const int STATE_SPACES = 6;
-
-    if (g_debug_ptr->getDebugTime() <= 0 ||
-        g_eventQueue_ptr->getTime() < g_debug_ptr->getDebugTime())
-        return;
-
-    ostream &out = *debug_cout_ptr;
-    out.flags(ios::right);
-    out << setw(TIME_SPACES) << g_eventQueue_ptr->getTime() << " ";
-    out << setw(ID_SPACES) << version << " ";
-    out << setw(COMP_SPACES) << component;
-    out << setw(EVENT_SPACES) << event << " ";
-
-    out.flags(ios::right);
-    out << setw(STATE_SPACES) << state;
-    out << ">";
-    out.flags(ios::left);
-    out << setw(STATE_SPACES) << next_state;
-
-    out << " " << addr << " " << note;
-
-    out << endl;
-}
-
 // Helper function
 static double
 process_memory_total()
@@ -764,15 +723,9 @@ Profiler::rubyWatch(int id)
 {
     uint64 tr = 0;
     Address watch_address = Address(tr);
-    const int ID_SPACES = 3;
-    const int TIME_SPACES = 7;
-
-    ostream &out = *debug_cout_ptr;
 
-    out.flags(ios::right);
-    out << setw(TIME_SPACES) << g_eventQueue_ptr->getTime() << " ";
-    out << setw(ID_SPACES) << id << " "
-        << "RUBY WATCH " << watch_address << endl;
+    DPRINTFN("%7s %3s RUBY WATCH %d\n", g_system_ptr->getTime(), id,
+        watch_address);
 
     // don't care about success or failure
     m_watch_address_set.insert(watch_address);