Skip to content

Commit 3a1cea6

Browse files
committed
[ngcore] Profiler
1 parent 678b449 commit 3a1cea6

File tree

8 files changed

+537
-119
lines changed

8 files changed

+537
-119
lines changed

libsrc/core/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
add_library(ngcore SHARED archive.cpp logging.cpp paje_trace.cpp utils.cpp)
2+
add_library(ngcore SHARED archive.cpp logging.cpp paje_trace.cpp utils.cpp profiler.cpp)
33

44
target_compile_definitions(ngcore PRIVATE NGCORE_EXPORTS)
55
if(NOT WIN32)
@@ -32,7 +32,7 @@ if(USE_PYTHON)
3232
endif(USE_PYTHON)
3333

3434
install(FILES ngcore.hpp archive.hpp type_traits.hpp version.hpp ngcore_api.hpp logging.hpp
35-
exception.hpp symboltable.hpp paje_trace.hpp utils.hpp
35+
exception.hpp symboltable.hpp paje_trace.hpp utils.hpp profiler.hpp
3636
DESTINATION ${NG_INSTALL_DIR_INCLUDE}/core COMPONENT netgen_devel)
3737

3838
if(ENABLE_CPP_CORE_GUIDELINES_CHECK)

libsrc/core/paje_trace.cpp

Lines changed: 71 additions & 63 deletions
Large diffs are not rendered by default.

libsrc/core/paje_trace.hpp

Lines changed: 19 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
#include <vector>
66
#include <x86intrin.h> // for __rdtsc() CPU time step counter
77

8-
#include "ngcore_api.hpp" // for NGCORE_API
98
#include "logging.hpp" // for logger
9+
#include "ngcore_api.hpp" // for NGCORE_API
10+
#include "utils.hpp"
1011

1112
namespace ngcore
1213
{
@@ -15,15 +16,11 @@ namespace ngcore
1516
class PajeTrace
1617
{
1718
public:
18-
typedef std::chrono::system_clock TClock;
19-
// typedef TClock::time_point TTimePoint;
20-
typedef size_t TTimePoint;
19+
using TClock = std::chrono::system_clock;
2120

2221
protected:
2322
std::shared_ptr<spdlog::logger> logger = GetLogger("PajeTrace");
2423
private:
25-
friend class TraceDisabler;
26-
2724
NGCORE_API static size_t max_tracefile_size;
2825
static bool trace_thread_counter;
2926
static bool trace_threads;
@@ -104,32 +101,32 @@ namespace ngcore
104101
std::vector<TimerEvent> timer_events;
105102
std::vector<std::vector<ThreadLink> > links;
106103

107-
TTimePoint GetTime()
108-
{
109-
// return TClock::now();
110-
return TTimePoint(__rdtsc());
111-
}
112-
113104
public:
114105
NGCORE_API void StopTracing();
115106

107+
PajeTrace() = delete;
108+
PajeTrace(const PajeTrace &) = delete;
109+
PajeTrace(PajeTrace &&) = delete;
116110
PajeTrace(int anthreads, std::string aname = "");
117111
~PajeTrace();
118112

113+
void operator=(const PajeTrace &) = delete;
114+
void operator=(PajeTrace &&) = delete;
115+
119116
void StartTimer(int timer_id)
120117
{
121118
if(!tracing_enabled) return;
122119
if(unlikely(timer_events.size() == max_num_events_per_thread))
123120
StopTracing();
124-
timer_events.push_back(TimerEvent{timer_id, GetTime(), true});
121+
timer_events.push_back(TimerEvent{timer_id, GetTimeCounter(), true});
125122
}
126123

127124
void StopTimer(int timer_id)
128125
{
129126
if(!tracing_enabled) return;
130127
if(unlikely(timer_events.size() == max_num_events_per_thread))
131128
StopTracing();
132-
timer_events.push_back(TimerEvent{timer_id, GetTime(), false});
129+
timer_events.push_back(TimerEvent{timer_id, GetTimeCounter(), false});
133130
}
134131

135132
NETGEN_INLINE int StartTask(int thread_id, int id, int id_type = Task::ID_NONE, int additional_value = -1)
@@ -139,15 +136,15 @@ namespace ngcore
139136
if(unlikely(tasks[thread_id].size() == max_num_events_per_thread))
140137
StopTracing();
141138
int task_num = tasks[thread_id].size();
142-
tasks[thread_id].push_back( Task{thread_id, id, id_type, additional_value, GetTime()} );
139+
tasks[thread_id].push_back( Task{thread_id, id, id_type, additional_value, GetTimeCounter()} );
143140
return task_num;
144141
}
145142

146143
void StopTask(int thread_id, int task_num)
147144
{
148145
if(!trace_threads && !trace_thread_counter) return;
149146
if(task_num>=0)
150-
tasks[thread_id][task_num].stop_time = GetTime();
147+
tasks[thread_id][task_num].stop_time = GetTimeCounter();
151148
}
152149

153150
void SetTask(int thread_id, int task_num, int additional_value) {
@@ -161,55 +158,34 @@ namespace ngcore
161158
if(!tracing_enabled) return;
162159
if(jobs.size() == max_num_events_per_thread)
163160
StopTracing();
164-
jobs.push_back( Job{job_id, &type, GetTime()} );
161+
jobs.push_back( Job{job_id, &type, GetTimeCounter()} );
165162
}
166163

167164
void StopJob()
168165
{
169166
if(tracing_enabled)
170-
jobs.back().stop_time = GetTime();
167+
jobs.back().stop_time = GetTimeCounter();
171168
}
172169

173170
void StartLink(int thread_id, int key)
174171
{
175172
if(!tracing_enabled) return;
176173
if(links[thread_id].size() == max_num_events_per_thread)
177174
StopTracing();
178-
links[thread_id].push_back( ThreadLink{thread_id, key, GetTime(), true} );
175+
links[thread_id].push_back( ThreadLink{thread_id, key, GetTimeCounter(), true} );
179176
}
180177

181178
void StopLink(int thread_id, int key)
182179
{
183180
if(!tracing_enabled) return;
184181
if(links[thread_id].size() == max_num_events_per_thread)
185182
StopTracing();
186-
links[thread_id].push_back( ThreadLink{thread_id, key, GetTime(), false} );
183+
links[thread_id].push_back( ThreadLink{thread_id, key, GetTimeCounter(), false} );
187184
}
188185

189-
void Write( std::string filename );
190-
191-
};
186+
void Write( const std::string & filename );
192187

193-
class TraceDisabler
194-
{
195-
bool trace_thread_counter;
196-
bool trace_threads;
197-
198-
public:
199-
TraceDisabler()
200-
{
201-
trace_thread_counter = PajeTrace::trace_thread_counter;
202-
PajeTrace::trace_thread_counter = false;
203-
trace_threads = PajeTrace::trace_threads;
204-
PajeTrace::trace_threads = false;
205-
}
206-
207-
~TraceDisabler()
208-
{
209-
PajeTrace::trace_thread_counter = trace_thread_counter;
210-
PajeTrace::trace_threads = trace_threads;
211-
}
212188
};
213-
}
189+
} // namespace ngcore
214190

215191
#endif // NETGEN_CORE_PAJE_TRACE_HPP

libsrc/core/profiler.cpp

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#include <mutex>
2+
3+
#include "profiler.hpp"
4+
5+
namespace ngcore
6+
{
7+
std::array<NgProfiler::TimerVal,NgProfiler::SIZE> NgProfiler::timers; // NOLINT
8+
9+
std::string NgProfiler::filename;
10+
11+
size_t dummy_thread_times[NgProfiler::SIZE];
12+
size_t * NgProfiler::thread_times = dummy_thread_times; // NOLINT
13+
size_t dummy_thread_flops[NgProfiler::SIZE];
14+
size_t * NgProfiler::thread_flops = dummy_thread_flops; // NOLINT
15+
16+
std::shared_ptr<spdlog::logger> logger = GetLogger("Profiler"); // NOLINT
17+
18+
NgProfiler :: NgProfiler()
19+
{
20+
for (auto & t : timers)
21+
{
22+
t.tottime = 0.0;
23+
t.usedcounter = 0;
24+
t.flops = 0.0;
25+
}
26+
}
27+
28+
NgProfiler :: ~NgProfiler()
29+
{
30+
if (filename.length())
31+
{
32+
logger->debug( "write profile to file {}", filename );
33+
FILE *prof = fopen(filename.c_str(),"w"); // NOLINT
34+
Print (prof);
35+
fclose(prof); // NOLINT
36+
}
37+
38+
}
39+
40+
void NgProfiler :: Print (FILE * prof)
41+
{
42+
int i = 0;
43+
for (auto & t : timers)
44+
{
45+
if (t.count != 0 || t.usedcounter != 0)
46+
{
47+
fprintf(prof,"job %3i calls %8li, time %6.4f sec",i,t.count,t.tottime); // NOLINT
48+
if(t.flops != 0.0)
49+
fprintf(prof,", MFlops = %6.2f",t.flops / (t.tottime) * 1e-6); // NOLINT
50+
if(t.loads != 0.0)
51+
fprintf(prof,", MLoads = %6.2f",t.loads / (t.tottime) * 1e-6); // NOLINT
52+
if(t.stores != 0.0)
53+
fprintf(prof,", MStores = %6.2f",t.stores / (t.tottime) * 1e-6); // NOLINT
54+
if(t.usedcounter)
55+
fprintf(prof," %s",t.name.c_str()); // NOLINT
56+
fprintf(prof,"\n"); // NOLINT
57+
}
58+
i++;
59+
}
60+
}
61+
62+
63+
int NgProfiler :: CreateTimer (const std::string & name)
64+
{
65+
static std::mutex createtimer_mutex;
66+
int nr = -1;
67+
{
68+
std::lock_guard<std::mutex> guard(createtimer_mutex);
69+
for (int i = SIZE-1; i > 0; i--)
70+
{
71+
auto & t = timers[i];
72+
if (!t.usedcounter)
73+
{
74+
t.usedcounter = 1;
75+
t.name = name;
76+
nr = i;
77+
break;
78+
}
79+
}
80+
}
81+
if (nr > -1) return nr;
82+
static bool first_overflow = true;
83+
if (first_overflow)
84+
{
85+
first_overflow = false;
86+
NgProfiler::logger->warn("no more timer available, reusing last one");
87+
}
88+
return 0;
89+
}
90+
91+
void NgProfiler :: Reset ()
92+
{
93+
for(auto & t : timers)
94+
{
95+
t.tottime = 0.0;
96+
t.count = 0;
97+
t.flops = 0.0;
98+
t.loads = 0;
99+
t.stores = 0;
100+
}
101+
}
102+
103+
NgProfiler prof; // NOLINT
104+
105+
106+
} // namespace ngcore

0 commit comments

Comments
 (0)