Selection of PAPI events via RTS command line
authormrchebas@gmail.com <unknown>
Thu, 9 Nov 2006 07:57:46 +0000 (07:57 +0000)
committermrchebas@gmail.com <unknown>
Thu, 9 Nov 2006 07:57:46 +0000 (07:57 +0000)
includes/RtsFlags.h
rts/Papi.c
rts/RtsFlags.c

index 6c4b230..d2236b4 100644 (file)
@@ -302,6 +302,18 @@ struct TRACE_FLAGS {
 
 /* Put them together: */
 
+#ifdef USE_PAPI
+struct PAPI_FLAGS {
+    nat     eventType;          /* The type of events to count */
+};
+
+#define PAPI_FLAG_CACHE_L1 1
+#define PAPI_FLAG_CACHE_L2 2
+#define PAPI_FLAG_BRANCH 3
+#define PAPI_FLAG_STALLS 4
+
+#endif
+
 typedef struct _RTS_FLAGS {
     /* The first portion of RTS_FLAGS is invariant. */
     struct GC_FLAGS         GcFlags;
@@ -319,6 +331,9 @@ typedef struct _RTS_FLAGS {
 #ifdef GRAN
     struct GRAN_FLAGS  GranFlags;
 #endif
+#ifdef USE_PAPI
+    struct PAPI_FLAGS   PapiFlags;
+#endif
 } RTS_FLAGS;
 
 #ifdef COMPILING_RTS_MAIN
index 8ce3cc2..5b4f785 100644 (file)
@@ -1,9 +1,10 @@
-
+#ifdef USE_PAPI /* ugly */
 
 #include "Papi.h"
 #include "Rts.h"
 #include "RtsUtils.h"
 #include "Stats.h"
+#include "RtsFlags.h"
 
 
 /* These constants specify which events to keep track of.
@@ -23,7 +24,13 @@ struct _papi_events {
   char * event_name;
 };
 
-#define PAPI_ADD_EVENT(EVENT) { EVENT, #EVENT }
+#define PAPI_ADD_EVENT(EVENT) \
+    {                        \
+       ASSERT(n_papi_events<MAX_PAPI_EVENTS);     \
+       papi_events[n_papi_events].event_code = EVENT;  \
+       papi_events[n_papi_events].event_name = #EVENT; \
+       n_papi_events++;                                \
+    }
 
 /* Beware, these counters are Opteron specific */
 #define FR_BR 0x40000040
@@ -47,7 +54,7 @@ struct _papi_events {
              papi_counter(EVENTSET,EVENT)*100.0/papi_counter(EVENTSET,EVENTTOT))
 
 /* Number of counted events, computed from size of papi_events */
-#define N_PAPI_EVENTS ((int)(sizeof(papi_events)/sizeof(struct _papi_events)))
+#define N_PAPI_EVENTS n_papi_events
 
 /* This is bad, it should be in a header */
 #define BIG_STRING_LEN 512
@@ -62,6 +69,10 @@ int GCEvents = PAPI_NULL;
 
 int papi_error;
 
+/* Arbitrary, to avoid using malloc */
+#define MAX_PAPI_EVENTS 10
+
+int n_papi_events = 0;
 
 /* If you want to add events to count, extend the
  * papi_events array and the papi_report function.
@@ -69,30 +80,34 @@ int papi_error;
 
 /* Events counted during GC and Mutator execution */
 /* There's a trailing comma, do all C compilers accept that? */
-static struct _papi_events papi_events[] = {
-  PAPI_ADD_EVENT(PAPI_TOT_CYC),
-#if PAPI_COUNT_BRANCHES
-  PAPI_ADD_EVENT(FR_BR),
-  PAPI_ADD_EVENT(FR_BR_MIS),
-  /* Docs are wrong? Opteron does not count indirect branch misses apparently */
-  PAPI_ADD_EVENT(FR_BR_MISCOMPARE),
-#endif
-#if PAPI_COUNT_STALLS
-  PAPI_ADD_EVENT(FR_DISPATCH_STALLS_BR),
-  PAPI_ADD_EVENT(FR_DISPATCH_STALLS_FULL_LS),
-#endif
-#if PAPI_COUNT_DCACHE1_MISSES
-  PAPI_ADD_EVENT(PAPI_L1_DCA),
-  PAPI_ADD_EVENT(PAPI_L1_DCM),
-#endif
-#if PAPI_COUNT_DCACHE2_MISSES
-  PAPI_ADD_EVENT(PAPI_L2_DCA),
-  PAPI_ADD_EVENT(PAPI_L2_DCM),
-#endif
+static struct _papi_events papi_events[MAX_PAPI_EVENTS];
+
+static void
+init_countable_events(void) 
+{
+    PAPI_ADD_EVENT(PAPI_TOT_CYC);
+    if(RtsFlags.PapiFlags.eventType==PAPI_FLAG_BRANCH) {
+       PAPI_ADD_EVENT(FR_BR);
+       PAPI_ADD_EVENT(FR_BR_MIS);
+       /* Docs are wrong? Opteron does not count indirect branch misses exclusively */
+       PAPI_ADD_EVENT(FR_BR_MISCOMPARE);
+    }
+    if(RtsFlags.PapiFlags.eventType==PAPI_FLAG_STALLS) {
+       PAPI_ADD_EVENT(FR_DISPATCH_STALLS_BR);
+       PAPI_ADD_EVENT(FR_DISPATCH_STALLS_FULL_LS);
+    }
+    if(RtsFlags.PapiFlags.eventType==PAPI_FLAG_CACHE_L1) {
+       PAPI_ADD_EVENT(PAPI_L1_DCA);
+       PAPI_ADD_EVENT(PAPI_L1_DCM);
+    }
+    if(RtsFlags.PapiFlags.eventType==PAPI_FLAG_CACHE_L2) {
+       PAPI_ADD_EVENT(PAPI_L2_DCA);
+       PAPI_ADD_EVENT(PAPI_L2_DCM);
+    }
 };
 
-long_long MutatorCounters[N_PAPI_EVENTS];
-long_long GCCounters[N_PAPI_EVENTS];
+long_long MutatorCounters[MAX_PAPI_EVENTS];
+long_long GCCounters[MAX_PAPI_EVENTS];
 
 
 /* Extract the value corresponding to an event */
@@ -118,28 +133,32 @@ papi_report(long_long PapiCounters[])
 
     /* I need to improve formatting aesthetics */
     PAPI_REPORT(PapiCounters,PAPI_TOT_CYC);
-#if PAPI_COUNT_BRANCHES
+    if(RtsFlags.PapiFlags.eventType==PAPI_FLAG_BRANCH) {
     PAPI_REPORT(PapiCounters,FR_BR);
     PAPI_REPORT(PapiCounters,FR_BR_MIS);
     PAPI_REPORT_PCT(PapiCounters,FR_BR_MIS,FR_BR);
     PAPI_REPORT_PCT(PapiCounters,FR_BR_MISCOMPARE,FR_BR);
-#endif
-#if PAPI_COUNT_STALLS
+    }
+
+    if(RtsFlags.PapiFlags.eventType==PAPI_FLAG_STALLS) {
     PAPI_REPORT(PapiCounters,FR_DISPATCH_STALLS_BR);
     PAPI_REPORT_PCT(PapiCounters,FR_DISPATCH_STALLS_BR,PAPI_TOT_CYC);
     PAPI_REPORT(PapiCounters,FR_DISPATCH_STALLS_FULL_LS);
     PAPI_REPORT_PCT(PapiCounters,FR_DISPATCH_STALLS_FULL_LS,PAPI_TOT_CYC);
-#endif
-#if PAPI_COUNT_DCACHE1_MISSES
+    }
+
+    if(RtsFlags.PapiFlags.eventType==PAPI_FLAG_CACHE_L1) {
     PAPI_REPORT(PapiCounters,PAPI_L1_DCA);
     PAPI_REPORT(PapiCounters,PAPI_L1_DCM);
     PAPI_REPORT_PCT(PapiCounters,PAPI_L1_DCM,PAPI_L1_DCA);
-#endif
-#if PAPI_COUNT_DCACHE2_MISSES
+    }
+
+    if(RtsFlags.PapiFlags.eventType==PAPI_FLAG_CACHE_L2) {
     PAPI_REPORT(PapiCounters,PAPI_L2_DCA);
     PAPI_REPORT(PapiCounters,PAPI_L2_DCM);
     PAPI_REPORT_PCT(PapiCounters,PAPI_L2_DCM,PAPI_L2_DCA);
-#endif
+    }
+
 }
 
 /* Add the events of papi_events into an event set */
@@ -160,6 +179,8 @@ void
 papi_init_eventsets(void)
 {
 
+    init_countable_events();
+
     /* One event set for the mutator and another for the GC */
     PAPI_CHECK( PAPI_create_eventset(&MutatorEvents));
     PAPI_CHECK( PAPI_create_eventset(&GCEvents));
@@ -195,3 +216,6 @@ papi_stop_gc_count(void)
       PAPI_CHECK( PAPI_accum(GCEvents,GCCounters));
       PAPI_CHECK( PAPI_stop(GCEvents,NULL));
 }
+
+
+#endif /* USE_PAPI */
index 7b8a4d1..b2bb9e7 100644 (file)
@@ -301,6 +301,10 @@ void initRtsFlagsDefaults(void)
 
     RtsFlags.TraceFlags.timestamp      = rtsFalse;
     RtsFlags.TraceFlags.sched          = rtsFalse;
+
+#ifdef USE_PAPI
+    RtsFlags.PapiFlags.eventType        = PAPI_FLAG_BRANCH;
+#endif
 }
 
 static const char *
@@ -449,6 +453,16 @@ usage_text[] = {
 #if defined(GRAN)  /* ToDo: fill in decent Docu here */
 "  -b...     All GranSim options start with -b; see GranSim User's Guide for details",
 #endif
+#if defined(USE_PAPI)
+"  -aX       Perform measurements using PAPI, it should be used with the -s<file> option.",
+"            Where X is one of:",
+"",
+/* "            y - cycles", */
+"            1 - level 1 cache misses",
+"            2 - level 2 cache misses",
+"            b - branch mispredictions",
+"            s - stalled cycles",
+#endif
 "",
 "RTS options may also be specified using the GHCRTS environment variable.",
 "",
@@ -647,6 +661,27 @@ error = rtsTrue;
                }
                break;
 
+#ifdef USE_PAPI
+             case 'a':
+               switch(rts_argv[arg][2]) {
+               case '1':
+                 RtsFlags.PapiFlags.eventType = PAPI_FLAG_CACHE_L1;
+                 break;
+               case '2':
+                 RtsFlags.PapiFlags.eventType = PAPI_FLAG_CACHE_L2;
+                 break;
+               case 'b':
+                 RtsFlags.PapiFlags.eventType = PAPI_FLAG_BRANCH;
+                 break;
+               case 's':
+                 RtsFlags.PapiFlags.eventType = PAPI_FLAG_STALLS;
+                 break;
+               default:
+                 bad_option( rts_argv[arg] );
+               }
+               break;
+#endif
+
              case 'B':
                RtsFlags.GcFlags.ringBell = rtsTrue;
                break;