-
Notifications
You must be signed in to change notification settings - Fork 58
/
papi_perf_counter.h
97 lines (85 loc) · 2.27 KB
/
papi_perf_counter.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#pragma once
/* for measurement of CPU cycles ..
*
* requires
* sudo apt-get install libpapi-dev papi-tools
* on debian/ubuntu linux distributions
*
*/
#ifdef HAVE_PAPI
#include <papi.h>
#endif
#include <stdio.h>
struct papi_perf_counter
{
papi_perf_counter()
: realTime(0.0F), processTime(0.0F), instructions(0LL), ipc(0.0F)
, started(false), finished(false), print_at_destruction(false)
{ }
papi_perf_counter(int _start, bool print_at_destruction_ = true)
: print_at_destruction(print_at_destruction_)
{
(void)_start;
start();
}
~papi_perf_counter()
{
if (print_at_destruction)
print(stderr);
}
bool start()
{
static bool reported_start_error = false;
#ifdef HAVE_PAPI
int ret = PAPI_ipc(&realTime, &processTime, &instructions, &ipc);
if (ret && !reported_start_error)
{
reported_start_error = true;
fprintf(stderr, "papi_perf_counter::start(): PAPI_ipc() returned error %d\n", ret);
}
#else
if (!reported_start_error)
{
reported_start_error = true;
fprintf(stderr, "papi_perf_counter::start(): no HAVE_PAPI\n");
}
int ret = 1;
#endif
started = (!ret);
finished = false;
return started;
}
bool finish()
{
papi_perf_counter end(1, false);
if (started && !finished && end.started)
{
realTime = end.realTime - realTime;
processTime = end.processTime - processTime;
instructions = end.instructions - instructions;
ipc = end.ipc;
finished = true;
return true;
}
return false;
}
void print(FILE *f = stdout)
{
if (started && !finished)
finish();
if (!started || !finished)
return;
double cycles = instructions / ipc;
fprintf(f, "real %g, process %g, instructions %lld, ins/cycle %f => cycles %g\n"
, realTime, processTime, instructions, ipc, cycles
);
started = false;
}
float realTime;
float processTime;
long long instructions;
float ipc;
bool started;
bool finished;
bool print_at_destruction;
};