forked from SCOREC/redev
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathredev_profile.h
144 lines (132 loc) · 4.36 KB
/
redev_profile.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#ifndef REDEV_PROFILE_H
#define REDEV_PROFILE_H
#include "redev_time.h"
#include <map>
#include <string> //std::string
#include <iostream> //std::string
namespace redev {
using ElapsedTime = double;
/**
* The Profiling class provides a basic capability to record the call count
* and time of functions.
*/
class Profiling {
private:
static Profiling *global_singleton_profiling;
using CallTime = std::pair<size_t,ElapsedTime>;
std::map<std::string, CallTime> callTime;
Profiling() {}
public:
//prevent calls to the copy and move assignment operators and ctors
//rule of 5 - #c21 - https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines
//! \{ supress doxygen warning
Profiling(const Profiling&) = delete; // copy constructor
Profiling& operator=(const Profiling&) = delete; // copy assignment
Profiling(Profiling&&) = delete; // move constructor
Profiling& operator=(Profiling&&) = delete; // move assignment
//! \}
/**
* Get the handle to the Profiling singleton instance.
*/
static Profiling *GetInstance() {
if (global_singleton_profiling == nullptr)
global_singleton_profiling = new Profiling;
return global_singleton_profiling;
}
/**
* Get the time spent in the specified function.
* @param[in] name the function name, case sensitive
*/
ElapsedTime GetTime(std::string name) {
if( callTime.count(name) )
return callTime[name].second;
else
return 0;
}
/**
* Get the call count of the specified function.
* @param[in] name the function name, case sensitive
*/
ElapsedTime GetCallCount(std::string name) {
if( callTime.count(name) )
return callTime[name].first;
else
return 0;
}
/**
* Increment the call count and increase the recorded time for the
* specified function by t.
* @param[in] name the function name, case sensitive
* @param[in] t recorded time in the function
*/
void AddTime(std::string name, ElapsedTime t) {
if(!callTime.count(name)) {
callTime[name].first = 1;
callTime[name].second = t;
} else {
callTime[name].first += 1;
callTime[name].second += t;
}
}
/**
* Write profiling data to the specified stream.
* @param[in,out] os stream object
*/
void Write(std::ostream& os) const {
os << "Profiling\n";
os << "name, callCount, time(s)\n";
for( auto nameCallsTime : callTime ) {
auto name = nameCallsTime.first;
auto calls = nameCallsTime.second.first;
auto time = nameCallsTime.second.second;
auto comma = std::string(", ");
os << name << comma << calls << comma << time << "\n";
}
}
};
/**
* Called at the beginning of an instrumented function.
*/
inline void begin_code(std::string name) {
}
/**
* Called at the end of an instrumented function.
*/
inline void end_code(std::string name, redev::ElapsedTime time) {
auto s = redev::Profiling::GetInstance();
s->AddTime(name,time);
}
/**
* ScopedTimer provides a simple mechanism to record the time spent in the
* calling scope.
* This is heavily based on omega_h/src/Omega_h_profile.hpp. Thanks Dan.
* https://github.com/sandialabs/omega_h/blob/a43850787b24f96d50807cee5688f09259e96b75/src/Omega_h_profile.hpp
*/
struct ScopedTimer {
//! \{ suppress doxygen warning
TimeType start;
std::string name;
//! \}
/**
* Time the callers scope and store it with the given name.
* @param[in] inName function name
*/
ScopedTimer(std::string inName)
: name(inName), start(getTime()) {
begin_code(name);
}
//! \{ suppress doxygen warning
~ScopedTimer() {
std::chrono::duration<double> t = getTime()-start; //cannot be 'auto t'
end_code(name,t.count());
}
ScopedTimer(ScopedTimer const&) = delete;
ScopedTimer(ScopedTimer&&) = delete;
ScopedTimer& operator=(ScopedTimer const&) = delete;
ScopedTimer& operator=(ScopedTimer&&) = delete;
//! \}
};
} //end redev
#define REDEV_FUNCTION_TIMER \
redev::ScopedTimer redev_scoped_function_timer(__FUNCTION__)
#endif