-
Notifications
You must be signed in to change notification settings - Fork 63
/
perf-timer.hpp
86 lines (59 loc) · 2.05 KB
/
perf-timer.hpp
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
/*
* perf-timer.hpp
*/
#ifndef PERF_TIMER_HPP_
#define PERF_TIMER_HPP_
#if USE_PERF_TIMER
#include <limits>
#include <memory>
#include "hedley.h"
#include "timer-info.hpp"
#define MAX_EXTRA_EVENTS 8
struct PerfNow {
constexpr static unsigned READING_COUNT = MAX_EXTRA_EVENTS + 1;
/* in principle the readings are unsigned values, but since we subtract two values to get a delta,
* there is a good chance of getting a small negative value (e.g., if the dummy run had more of a
* given event than the actual run) which if unsigned produces a large nonsense value.
*/
int64_t readings[READING_COUNT];
/* return the unhalted clock cycles value (PFC_FIXEDCNT_CPU_CLK_UNHALTED) */
uint64_t getClk() const { return readings[0]; }
};
class PerfTimer : public TimerInfo {
public:
typedef PerfNow now_t;
typedef PerfNow delta_t;
PerfTimer(Context &c);
virtual void init(Context &) override;
// HEDLEY_ALWAYS_INLINE
static now_t now();
static TimingResult to_result(const PerfTimer& ti, PerfNow delta);
/*
* Return the delta of a and b, that is a minus b.
*/
static PerfNow delta(const PerfNow& a, const PerfNow& b);
static uint64_t aggr_value(const PerfNow& now) {
return now.getClk();
}
static PerfNow aggregate(const PerfNow *begin, const PerfNow *end);
virtual void listEvents(Context& c) override;
virtual ~PerfTimer();
};
struct NamedEvent {
std::string name;
std::string header;
NamedEvent(const std::string& name);
NamedEvent(const std::string& name, const std::string& header);
bool operator==(const NamedEvent& e) const {
return name == e.name && header == e.header;
}
};
/* parse an --extra-events string of perf events
* Basically split events on commas, but commas in-between / characters
* are ignored for splitting.
* So 'cpu/123,456/,cpu/xxx,yyy/' is split as two tokens:
* 'cpu/123,456' and 'cpu/xxx,yyy/'
*/
std::vector<NamedEvent> parsePerfEvents(const std::string& event_string);
#endif
#endif /* PERF_TIMER_HPP_ */