Multi-core Hash Joins
Main-memory hash join implementations for multi-core CPUs
perf_counters.c
1/* @version $Id: perf_counters.c 3017 2012-12-07 10:56:20Z bcagri $ */
2
3#include "perf_counters.h"
4
6#if defined(__cplusplus) && defined(PERF_COUNTERS)
7
8#include <iostream>
9#include <fstream>
10#include <string.h>
11#include <stdlib.h>
12#include <string.h>
13
14#include "cpucounters.h" /* intel perf counters monitor */
15
16using namespace std;
17
20static PCM * pcmInstance;
21
22#if PER_CORE==1
23static CoreCounterState before_state;
24static CoreCounterState after_state;
25#elif PER_SOCKET==1
26static SocketCounterState before_state;
27static SocketCounterState after_state;
28#else
29static SystemCounterState before_state;
30static SystemCounterState after_state;
31#endif
32
36static PCM::CustomCoreEventDescription MyEvents[4];
37static std::string MyEventNames[4];
38static int numEvents;
40static double eventAcc[12] = {0.0};
41
42
44char * PCM_CONFIG;
45
47char * PCM_OUT;
48
49static char *
50mystrdup (const char *s)
51{
52 char *ss = (char*) malloc (strlen (s) + 1);
53
54 if (ss != NULL)
55 memcpy (ss, s, strlen(s) + 1);
56
57 return ss;
58}
59
60void
61PCM_initPerformanceMonitor(const char * pcmcfg, const char * pcmout)
62{
63 PCM * m = PCM::getInstance();
64 PCM::ErrorCode status;
65 pcmInstance = m;
66 numEvents = 0;
67
68 if(pcmcfg)
69 PCM_CONFIG = mystrdup(pcmcfg);
70 /* else */
71 /* PCM_CONFIG = NULL; */
72
73 if(pcmout)
74 PCM_OUT = mystrdup(pcmout);
75 /* else */
76 /* PCM_CONFIG = NULL; */
77
78 if(PCM_CONFIG) {
79
80 ifstream inpf(PCM_CONFIG);
81
94 while (!inpf.eof() && numEvents < 4) {
95 inpf >> MyEventNames[numEvents]
96 >> hex >> MyEvents[numEvents].event_number
97 >> hex >> MyEvents[numEvents].umask_value;
98 numEvents++;
99 }
100 inpf.close();
101
102 if (pcmInstance->good())
103 status = pcmInstance->program(PCM::CUSTOM_CORE_EVENTS, MyEvents);
104 }
105 else {
106 status = pcmInstance->program();
107 }
108
109 switch (status)
110 {
111 case PCM::Success:
112 break;
113 case PCM::MSRAccessDenied:
114 cout << "Access to Intel(r) Performance Counter Monitor has denied "
115 << "(no MSR or PCI CFG space access)." << endl;
116 break;
117 case PCM::PMUBusy:
118 cout << "Access to Intel(r) Performance Counter Monitor has denied "
119 << "(Performance Monitoring Unit is occupied by other application)."
120 << "Try to stop the application that uses PMU." << endl;
121 cout << "Alternatively you can try to reset PMU configuration at your"
122 << " own risk. Try to reset? (y/n)" << endl;
123 char yn;
124 std::cin >> yn;
125 if ('y' == yn)
126 {
127 m->resetPMU();
128 cout << "PMU configuration has been reset. Try to rerun the "
129 << "program again." << endl;
130 }
131 break;
132 default:
133 cout << "Access to Intel(r) Performance Counter Monitor has denied "
134 << "(Unknown error)." << endl;
135 break;
136 }
137
138}
139
140void
141PCM_start()
142{
143#if PER_CORE==1
144 before_state = getCoreCounterState(0);
145#elif PER_SOCKET==1
146 before_state = getSocketCounterState(0);
147#else
148 before_state = getSystemCounterState();
149#endif
150}
151
152void
153PCM_stop()
154{
155#if PER_CORE==1
156 after_state = getCoreCounterState(0);
157#elif PER_SOCKET==1
158 after_state = getSocketCounterState(0);
159#else
160 after_state = getSystemCounterState();
161#endif
162}
163
164void
166{
167 ostream * out;
168 ofstream outf;
169
170 if(PCM_OUT) {
171 outf.open(PCM_OUT, ios::app);
172 out = &outf;
173 }
174 else {
175 out = &cout;
176 }
177
178 (*out) << "Instructions-retired "
179 << getInstructionsRetired(before_state, after_state) << endl;
180 (*out) << "Active-cycles "
181 << getCycles(before_state, after_state) << endl;
182 (*out) << "IPC "
183 << getIPC(before_state, after_state) << endl;
184
185 if(numEvents == 0){
186 (*out) << "L2Misses "
187 << getL2CacheMisses(before_state, after_state) << endl;
188 (*out) << "L3Misses "
189 << getL3CacheMisses(before_state, after_state) << endl;
190 (*out) << "L2HitRatio "
191 << getL2CacheHitRatio(before_state, after_state) << endl;
192 (*out) << "L3HitRatio "
193 << getL3CacheHitRatio(before_state, after_state) << endl;
194
195 (*out) << "CyclesLostDueL2CacheMisses "
196 << getCyclesLostDueL2CacheMisses(before_state, after_state) << endl;
197 (*out) << "CyclesLostDueL3CacheMisses "
198 << getCyclesLostDueL3CacheMisses(before_state, after_state) << endl;
199#if PER_CORE==0
200 (*out) << "BytesFromMC " << getBytesReadFromMC(before_state, after_state) << endl;
201 (*out) << "BytesWrittenToMC " << getBytesWrittenToMC(before_state, after_state) << endl;
202#endif
203 }
204
205 for(int i = 0; i < numEvents; i++) {
206 (*out) << MyEventNames[i] << " "
207 << getNumberOfCustomEvents(i, before_state, after_state)
208 << endl;
209 }
210
211 if(PCM_OUT)
212 outf.close();
213}
214
215void
217{
218 // "Instructions-retired "
219 eventAcc[0] += getInstructionsRetired(before_state, after_state);
220 // (*out) << "Active-cycles "
221 eventAcc[1] += getCycles(before_state, after_state);
222 // (*out) << "IPC "
223 eventAcc[2] += getIPC(before_state, after_state);
224
225 if(numEvents == 0){
226 //(*out) << "L2Misses "
227 eventAcc[3] += getL2CacheMisses(before_state, after_state);
228 // (*out) << "L3Misses "
229 eventAcc[4] += getL3CacheMisses(before_state, after_state);
230 //(*out) << "L2HitRatio "
231 eventAcc[5] += getL2CacheHitRatio(before_state, after_state);
232 // (*out) << "L3HitRatio "
233 eventAcc[6] += getL3CacheHitRatio(before_state, after_state);
234
235 //(*out) << "CyclesLostDueL2CacheMisses "
236 eventAcc[7] += getCyclesLostDueL2CacheMisses(before_state, after_state);
237 //(*out) << "CyclesLostDueL3CacheMisses "
238 eventAcc[8] += getCyclesLostDueL3CacheMisses(before_state, after_state);
239
240#if PER_CORE==0
241 //(*out) << "BytesFromMC " <<
242 eventAcc[9] += getBytesReadFromMC(before_state, after_state);
243 //(*out) << "BytesWrittenToMC " <<
244 eventAcc[10] += getBytesWrittenToMC(before_state, after_state);
245#endif
246 }
247
248 for(int i = 0; i < numEvents; i++) {
249 //(*out) << MyEventNames[i] << " "
250 eventAcc[i+3] = getNumberOfCustomEvents(i, before_state, after_state);
251 }
252}
253
254void
256{
257 ostream * out;
258 ofstream outf;
259
260 if(PCM_OUT) {
261 outf.open(PCM_OUT, ios::app);
262 out = &outf;
263 }
264 else {
265 out = &cout;
266 }
267
268 (*out) << "Instructions-retired " << eventAcc[0] << endl;
269 (*out) << "Active-cycles " << eventAcc[1] << endl;
270 (*out) << "IPC " << eventAcc[2] << endl;
271
272 if(numEvents == 0){
273 (*out) << "L2Misses " << eventAcc[3] << endl;
274 (*out) << "L3Misses " << eventAcc[4] << endl;
275 (*out) << "L2HitRatio "<< eventAcc[5] << endl;
276 (*out) << "L3HitRatio "<< eventAcc[6] << endl;
277
278 (*out) << "CyclesLostDueL2CacheMisses "
279 << eventAcc[7] << endl;
280 (*out) << "CyclesLostDueL3CacheMisses "
281 << eventAcc[8] << endl;
282
283 (*out) << "BytesFromMC " << eventAcc[9] << endl;
284 (*out) << "BytesWrittenToMC " << eventAcc[10] << endl;
285 }
286
287 for(int i = 0; i < numEvents; i++) {
288 (*out) << MyEventNames[i] << " " << eventAcc[i+3] << endl;
289 }
290
291 if(PCM_OUT)
292 outf.close();
293}
294
295void
297{
298 pcmInstance->cleanup();
299
300 if(PCM_CONFIG)
301 free(PCM_CONFIG);
302
303 if(PCM_OUT)
304 free(PCM_OUT);
305}
306
307void
308PCM_log(char * msg)
309{
310 ostream * out;
311 ofstream outf;
312
313 if(PCM_OUT) {
314 outf.open(PCM_OUT, ios::app);
315 out = &outf;
316 }
317 else {
318 out = &cout;
319 }
320
321 (*out) << msg << std::endl;
322
323 if(PCM_OUT)
324 outf.close();
325}
326
327#else
328
329/* just placeholders */
330void PCM_initPerformanceMonitor(const char * pcmcfg, const char * pcmout){}
331void PCM_start(){}
332void PCM_stop(){}
337void PCM_log(char * msg){}
338
339#endif /*PERF_COUNTERS*/
void PCM_initPerformanceMonitor(const char *pcmcfg, const char *pcmout)
void PCM_printAccumulators()
void PCM_start()
void PCM_stop()
void PCM_cleanup()
char * PCM_OUT
void PCM_accumulate()
void PCM_printResults()
char * PCM_CONFIG
void PCM_log(char *msg)
An interface to the Intel Performance Counters Monitoring.