9 /* These constants specify which events to keep track of.
10 * Probably it is better to count one set of events at a time.
11 * The reason is that processors have limited counters and
12 * multiplexing is not enabled (yet).
14 #define PAPI_COUNT_BRANCHES 0
15 /* The one below is Opteron specific.
17 #define PAPI_COUNT_STALLS 0
18 #define PAPI_COUNT_DCACHE1_MISSES 1
19 #define PAPI_COUNT_DCACHE2_MISSES 0
26 #define PAPI_ADD_EVENT(EVENT) { EVENT, #EVENT }
28 /* Beware, these counters are Opteron specific */
29 #define FR_BR 0x40000040
30 #define FR_BR_MIS 0x40000041
31 #define FR_BR_MISCOMPARE 0x40000048
32 #define DC_ACCESS 0x40000019
33 #define DC_MISS 0x4000001a
34 #define FR_DISPATCH_STALLS_BR 0x40000055
35 #define FR_DISPATCH_STALLS_FULL_LS 0x4000005b
37 /* Report the value of a counter */
38 #define PAPI_REPORT(EVENTSET,EVENT) \
40 ullong_format_string(papi_counter(EVENTSET,EVENT),temp,rtsTrue/*commas*/); \
41 statsPrintf(" (" #EVENT ") : %s\n",temp); \
44 /* Report the value of a counter as a percentage of another counter */
45 #define PAPI_REPORT_PCT(EVENTSET,EVENT,EVENTTOT) \
46 statsPrintf(" (" #EVENT ") %% of (" #EVENTTOT ") : %.1f%%\n", \
47 papi_counter(EVENTSET,EVENT)*100.0/papi_counter(EVENTSET,EVENTTOT))
49 /* Number of counted events, computed from size of papi_events */
50 #define N_PAPI_EVENTS ((int)(sizeof(papi_events)/sizeof(struct _papi_events)))
52 /* This is bad, it should be in a header */
53 #define BIG_STRING_LEN 512
55 /* While PAPI reporting is going on this flag is on */
56 int papi_is_reporting;
58 /* Event sets and counter arrays for GC and mutator */
60 int MutatorEvents = PAPI_NULL;
61 int GCEvents = PAPI_NULL;
66 /* If you want to add events to count, extend the
67 * papi_events array and the papi_report function.
70 /* Events counted during GC and Mutator execution */
71 /* There's a trailing comma, do all C compilers accept that? */
72 static struct _papi_events papi_events[] = {
73 PAPI_ADD_EVENT(PAPI_TOT_CYC),
74 #if PAPI_COUNT_BRANCHES
75 PAPI_ADD_EVENT(FR_BR),
76 PAPI_ADD_EVENT(FR_BR_MIS),
77 /* Docs are wrong? Opteron does not count indirect branch misses apparently */
78 PAPI_ADD_EVENT(FR_BR_MISCOMPARE),
81 PAPI_ADD_EVENT(FR_DISPATCH_STALLS_BR),
82 PAPI_ADD_EVENT(FR_DISPATCH_STALLS_FULL_LS),
84 #if PAPI_COUNT_DCACHE1_MISSES
85 PAPI_ADD_EVENT(PAPI_L1_DCA),
86 PAPI_ADD_EVENT(PAPI_L1_DCM),
88 #if PAPI_COUNT_DCACHE2_MISSES
89 PAPI_ADD_EVENT(PAPI_L2_DCA),
90 PAPI_ADD_EVENT(PAPI_L2_DCM),
94 long_long MutatorCounters[N_PAPI_EVENTS];
95 long_long GCCounters[N_PAPI_EVENTS];
98 /* Extract the value corresponding to an event */
100 papi_counter(long_long values[],int event)
103 for(i=0;i<N_PAPI_EVENTS;i++) {
104 if(papi_events[i].event_code==event) {
108 /* Passed a wrong event? */
109 debugBelch("Event %d is not part of event set\n",event);
113 /* This function reports counters for GC and mutator */
115 papi_report(long_long PapiCounters[])
117 char temp[BIG_STRING_LEN];
119 /* I need to improve formatting aesthetics */
120 PAPI_REPORT(PapiCounters,PAPI_TOT_CYC);
121 #if PAPI_COUNT_BRANCHES
122 PAPI_REPORT(PapiCounters,FR_BR);
123 PAPI_REPORT(PapiCounters,FR_BR_MIS);
124 PAPI_REPORT_PCT(PapiCounters,FR_BR_MIS,FR_BR);
125 PAPI_REPORT_PCT(PapiCounters,FR_BR_MISCOMPARE,FR_BR);
127 #if PAPI_COUNT_STALLS
128 PAPI_REPORT(PapiCounters,FR_DISPATCH_STALLS_BR);
129 PAPI_REPORT_PCT(PapiCounters,FR_DISPATCH_STALLS_BR,PAPI_TOT_CYC);
130 PAPI_REPORT(PapiCounters,FR_DISPATCH_STALLS_FULL_LS);
131 PAPI_REPORT_PCT(PapiCounters,FR_DISPATCH_STALLS_FULL_LS,PAPI_TOT_CYC);
133 #if PAPI_COUNT_DCACHE1_MISSES
134 PAPI_REPORT(PapiCounters,PAPI_L1_DCA);
135 PAPI_REPORT(PapiCounters,PAPI_L1_DCM);
136 PAPI_REPORT_PCT(PapiCounters,PAPI_L1_DCM,PAPI_L1_DCA);
138 #if PAPI_COUNT_DCACHE2_MISSES
139 PAPI_REPORT(PapiCounters,PAPI_L2_DCA);
140 PAPI_REPORT(PapiCounters,PAPI_L2_DCM);
141 PAPI_REPORT_PCT(PapiCounters,PAPI_L2_DCM,PAPI_L2_DCA);
145 /* Add the events of papi_events into an event set */
147 papi_add_events(int EventSet)
150 for(i=0;i<N_PAPI_EVENTS;i++) {
151 if((papi_error=PAPI_add_event(EventSet,
152 papi_events[i].event_code))
154 debugBelch("Failed adding %s to event set with error code %d\n",
155 papi_events[i].event_name,papi_error);
160 papi_init_eventsets(void)
163 /* One event set for the mutator and another for the GC */
164 PAPI_CHECK( PAPI_create_eventset(&MutatorEvents));
165 PAPI_CHECK( PAPI_create_eventset(&GCEvents));
167 /* Both sets contain the same events */
168 papi_add_events(MutatorEvents);
169 papi_add_events(GCEvents);
174 papi_start_mutator_count(void)
176 PAPI_CHECK( PAPI_start(MutatorEvents));
180 papi_stop_mutator_count(void)
182 PAPI_CHECK( PAPI_accum(MutatorEvents,MutatorCounters));
183 PAPI_CHECK( PAPI_stop(MutatorEvents,NULL));
187 papi_start_gc_count(void)
189 PAPI_CHECK( PAPI_start(GCEvents));
193 papi_stop_gc_count(void)
195 PAPI_CHECK( PAPI_accum(GCEvents,GCCounters));
196 PAPI_CHECK( PAPI_stop(GCEvents,NULL));