X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FPapi.c;fp=rts%2FPapi.c;h=8ce3cc2381134a8e083961c8af3d038e82218af1;hb=fe07f054d7ae5e10b14d5fed730fe4424dabd587;hp=0000000000000000000000000000000000000000;hpb=74a87d705449e2f9ad4021aeebf8149ce35a6a2e;p=ghc-hetmet.git diff --git a/rts/Papi.c b/rts/Papi.c new file mode 100644 index 0000000..8ce3cc2 --- /dev/null +++ b/rts/Papi.c @@ -0,0 +1,197 @@ + + +#include "Papi.h" +#include "Rts.h" +#include "RtsUtils.h" +#include "Stats.h" + + +/* These constants specify which events to keep track of. + * Probably it is better to count one set of events at a time. + * The reason is that processors have limited counters and + * multiplexing is not enabled (yet). + */ +#define PAPI_COUNT_BRANCHES 0 +/* The one below is Opteron specific. + */ +#define PAPI_COUNT_STALLS 0 +#define PAPI_COUNT_DCACHE1_MISSES 1 +#define PAPI_COUNT_DCACHE2_MISSES 0 + +struct _papi_events { + int event_code; + char * event_name; +}; + +#define PAPI_ADD_EVENT(EVENT) { EVENT, #EVENT } + +/* Beware, these counters are Opteron specific */ +#define FR_BR 0x40000040 +#define FR_BR_MIS 0x40000041 +#define FR_BR_MISCOMPARE 0x40000048 +#define DC_ACCESS 0x40000019 +#define DC_MISS 0x4000001a +#define FR_DISPATCH_STALLS_BR 0x40000055 +#define FR_DISPATCH_STALLS_FULL_LS 0x4000005b + +/* Report the value of a counter */ +#define PAPI_REPORT(EVENTSET,EVENT) \ + { \ + ullong_format_string(papi_counter(EVENTSET,EVENT),temp,rtsTrue/*commas*/); \ + statsPrintf(" (" #EVENT ") : %s\n",temp); \ + } + +/* Report the value of a counter as a percentage of another counter */ +#define PAPI_REPORT_PCT(EVENTSET,EVENT,EVENTTOT) \ + statsPrintf(" (" #EVENT ") %% of (" #EVENTTOT ") : %.1f%%\n", \ + 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))) + +/* This is bad, it should be in a header */ +#define BIG_STRING_LEN 512 + +/* While PAPI reporting is going on this flag is on */ +int papi_is_reporting; + +/* Event sets and counter arrays for GC and mutator */ + +int MutatorEvents = PAPI_NULL; +int GCEvents = PAPI_NULL; + +int papi_error; + + +/* If you want to add events to count, extend the + * papi_events array and the papi_report function. + */ + +/* 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 +}; + +long_long MutatorCounters[N_PAPI_EVENTS]; +long_long GCCounters[N_PAPI_EVENTS]; + + +/* Extract the value corresponding to an event */ +long_long +papi_counter(long_long values[],int event) +{ + int i; + for(i=0;i