Anonymous avatar Anonymous committed f0de518

reason summary

Comments (0)

Files changed (1)

 #include <stdio.h>
 #include <vector>
+#include <algorithm>
 
 #include "tracevis.h"
 #include "tracevis_gen.h"
   }
 };
 
+// Extended reason, also includes states
+class EReason {
+  int         n;
+public:
+  EReason(const Record& rec) {
+    if (rec.r)
+      n = rec.r;
+    else
+      n = R_COUNT + rec.s;
+  }
+
+  EReason(int n) : n(n) {}
+
+  operator const char* () const {
+    if (n == R_COUNT)
+      return "start";
+    if (n < R_COUNT)
+      return reason_names[n];
+    return state_names[n - R_COUNT];
+  }
+
+  operator int () const {
+    return n;
+  }
+};
+
+const int ER_COUNT = R_COUNT + S_COUNT;
+
+class ReasonCounter {
+public:
+  EReason r;
+  uint64  t;
+  int     n;
+
+  ReasonCounter(EReason r) : r(r), t(0), n(0) {}
+
+  ReasonCounter& operator+=(uint64 dt) {
+    t += dt;
+    n += 1;
+    return *this;
+  }
+};
+
+bool operator<(const ReasonCounter& c1, const ReasonCounter& c2)
+{
+  return c1.t > c2.t;
+}
+
 class History {
 public:
   uint64                  state_summary[S_COUNT];
   std::vector<Record>     stack;
 
-  History() {
+  Record                  to_interp;
+  std::vector<ReasonCounter>   reason_summary;
+
+  History() : to_interp(0, 0, 0) {
     for (int i = 0; i < S_COUNT; ++i) {
       state_summary[i] = 0;
     }
+    for (int i = 0; i < ER_COUNT; ++i) {
+      reason_summary.push_back(ReasonCounter(i));
+    }
   }
 
   void transition(const Record& rec0, const Record& rec1) {
     uint64 dt = rec1.t - rec0.t;
     state_summary[rec0.s] += dt;
+
+    // Transition to interpreter
+    if (rec0.s != S_INTERP && rec1.s == S_INTERP) {
+      to_interp.t = rec1.t;
+      to_interp.s = rec0.s;
+      to_interp.r = rec1.r;
+    }
+
+#if 1
+    // Transition from interpreter
+    if (rec0.s == S_INTERP && rec1.s != S_INTERP) {
+      //reason_summary[EReason(to_interp)] += rec1.t - to_interp.t;
+      reason_summary[EReason(to_interp)] += rec1.t - to_interp.t;
+    }
+#else
+    if (rec0.s == S_INTERP)
+      reason_summary[EReason(to_interp)] += dt;
+#endif
   }
 
   void enter(const Record& rec) {
     prior.r = rec.r;
   }
 
-  void list_summary() const {
+  void list_state_summary() const {
+    printf("Activity summary:\n");
+    printf("%-18s %12s\n", "Activity", "time (ms)");
+    rep('=', 31);
     uint64 subtotal = 0;
     for (int i = 1; i < S_COUNT; ++i) {
       subtotal += state_summary[i];
-      printf("%-12s %12.6f\n", state_names[i], state_summary[i] / CPU_SPEED * 1000);
+      printf("%-18s %12.6f\n", state_names[i], state_summary[i] / CPU_SPEED * 1000);
     }
-    rep('-', 25);
-    printf("%-12s %12.6f\n", "Subtotal", subtotal / CPU_SPEED * 1000);
-    printf("%-12s %12.6f\n", "Non-JS", state_summary[0] / CPU_SPEED * 1000);
-    rep('=', 25);
-    printf("%-12s %12.6f\n", "Total", (state_summary[0]+subtotal) / CPU_SPEED * 1000);
+    rep('-', 31);
+    printf("%-18s %12.6f\n", "Subtotal", subtotal / CPU_SPEED * 1000);
+    printf("%-18s %12.6f\n", "Non-JS", state_summary[0] / CPU_SPEED * 1000);
+    rep('=', 31);
+    printf("%-18s %12.6f\n", "Total", (state_summary[0]+subtotal) / CPU_SPEED * 1000);
+  }
+
+  void list_reason_summary() {
+    printf("Reasons for transitions to intepreter:\n");
+    printf("%-18s %12s %8s %12s\n", 
+	   "reason", "time (ms)", "count", "avg time (ms)");
+    rep('=', 53);
+
+    // FIXME: don't mutate original
+    std::sort(reason_summary.begin(), reason_summary.end());
+    uint64 subtotal = 0;
+    for (std::vector<ReasonCounter>::iterator p = reason_summary.begin();
+	 p < reason_summary.end(); ++p) {
+      ReasonCounter& c = *p;
+      if (c.t == 0)
+	break;
+      subtotal += c.t;
+      printf("%-18s %12.3f %8d %12.3f\n", 
+	     static_cast<const char*>(c.r), 
+	     c.t / CPU_SPEED * 1000,
+	     c.n,
+	     c.t / CPU_SPEED * 1000 / c.n
+	     );
+    }
+    rep('=', 53);
+    printf("%-18s %12.3f\n", "Total", (subtotal) / CPU_SPEED * 1000);
   }
 };
 
       process_record(h, recs[i]);
     }
   }
-  h.list_summary();
+  h.list_state_summary();
+  printf("\n");
+  h.list_reason_summary();
   return 0;
 }
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.