|
1
|
1 #pragma once
|
|
|
2
|
|
|
3 #include "string_base.h"
|
|
|
4
|
|
|
5 #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
|
|
|
6
|
|
|
7 #define PFC_HAVE_PROFILER
|
|
|
8
|
|
|
9 #include <intrin.h>
|
|
|
10 namespace pfc {
|
|
|
11 class profiler_static {
|
|
|
12 public:
|
|
|
13 profiler_static(const char * p_name);
|
|
|
14 ~profiler_static();
|
|
|
15 void add_time(t_int64 delta) { total_time += delta;num_called++; }
|
|
|
16 private:
|
|
|
17 const char * name;
|
|
|
18 t_uint64 total_time, num_called;
|
|
|
19 };
|
|
|
20
|
|
|
21 class profiler_local {
|
|
|
22 public:
|
|
|
23 profiler_local(profiler_static * p_owner) {
|
|
|
24 owner = p_owner;
|
|
|
25 start = __rdtsc();
|
|
|
26 }
|
|
|
27 ~profiler_local() {
|
|
|
28 t_int64 end = __rdtsc();
|
|
|
29 owner->add_time(end - start);
|
|
|
30 }
|
|
|
31 private:
|
|
|
32 t_int64 start;
|
|
|
33 profiler_static * owner;
|
|
|
34 };
|
|
|
35
|
|
|
36 }
|
|
|
37 #define profiler(name) \
|
|
|
38 static pfc::profiler_static profiler_static_##name(#name); \
|
|
|
39 pfc::profiler_local profiler_local_##name(&profiler_static_##name);
|
|
|
40
|
|
|
41
|
|
|
42 #endif
|
|
|
43
|
|
|
44 #ifdef _WIN32
|
|
|
45
|
|
|
46 namespace pfc {
|
|
|
47 typedef uint64_t tickcount_t;
|
|
|
48 inline tickcount_t getTickCount() { return GetTickCount64(); }
|
|
|
49
|
|
|
50 class hires_timer {
|
|
|
51 public:
|
|
|
52 hires_timer() : m_start() {}
|
|
|
53 static hires_timer create_and_start() {
|
|
|
54 hires_timer t; t.start(); return t;
|
|
|
55 }
|
|
|
56 void start() {
|
|
|
57 m_start = g_query();
|
|
|
58 }
|
|
|
59 double query() const {
|
|
|
60 return _query( g_query() );
|
|
|
61 }
|
|
|
62 double query_reset() {
|
|
|
63 t_uint64 current = g_query();
|
|
|
64 double ret = _query(current);
|
|
|
65 m_start = current;
|
|
|
66 return ret;
|
|
|
67 }
|
|
|
68 pfc::string8 queryString(unsigned precision = 6) const {
|
|
|
69 return pfc::format_time_ex( query(), precision ).get_ptr();
|
|
|
70 }
|
|
|
71 private:
|
|
|
72 double _query(t_uint64 p_val) const {
|
|
|
73 return (double)( p_val - m_start ) * m_mul;
|
|
|
74 }
|
|
|
75 static t_uint64 g_query() {
|
|
|
76 LARGE_INTEGER val;
|
|
|
77 if (!QueryPerformanceCounter(&val)) throw pfc::exception_not_implemented();
|
|
|
78 return val.QuadPart;
|
|
|
79 }
|
|
|
80 static double init_mul() {
|
|
|
81 return 1.0 / (double)g_query_freq();
|
|
|
82 }
|
|
|
83 static t_uint64 g_query_freq() {
|
|
|
84 LARGE_INTEGER val;
|
|
|
85 if (!QueryPerformanceFrequency(&val)) throw pfc::exception_not_implemented();
|
|
|
86 PFC_ASSERT(val.QuadPart > 0);
|
|
|
87 return val.QuadPart;
|
|
|
88 }
|
|
|
89 t_uint64 m_start;
|
|
|
90 double m_mul = init_mul();
|
|
|
91 };
|
|
|
92
|
|
|
93 class lores_timer {
|
|
|
94 public:
|
|
|
95 lores_timer() {}
|
|
|
96 static lores_timer create_and_start() {
|
|
|
97 lores_timer t; t.start(); return t;
|
|
|
98 }
|
|
|
99 void start() {
|
|
|
100 _start(getTickCount());
|
|
|
101 }
|
|
|
102
|
|
|
103 double query() const {
|
|
|
104 return _query(getTickCount());
|
|
|
105 }
|
|
|
106 double query_reset() {
|
|
|
107 tickcount_t time = getTickCount();
|
|
|
108 double ret = _query(time);
|
|
|
109 _start(time);
|
|
|
110 return ret;
|
|
|
111 }
|
|
|
112 pfc::string8 queryString(unsigned precision = 3) const {
|
|
|
113 return pfc::format_time_ex( query(), precision ).get_ptr();
|
|
|
114 }
|
|
|
115 private:
|
|
|
116 void _start(tickcount_t p_time) {
|
|
|
117 m_start = p_time;
|
|
|
118 }
|
|
|
119 double _query(tickcount_t p_time) const {
|
|
|
120 return (double)(p_time - m_start) / 1000.0;
|
|
|
121 }
|
|
|
122 t_uint64 m_start = 0;
|
|
|
123 };
|
|
|
124
|
|
|
125 class media_timer {
|
|
|
126 typedef DWORD val_t;
|
|
|
127 static val_t _now() { return timeGetTime(); }
|
|
|
128 public:
|
|
|
129 void start() {
|
|
|
130 _start(_now());
|
|
|
131 }
|
|
|
132 double query() const {
|
|
|
133 return _query(_now());
|
|
|
134 }
|
|
|
135 double query_reset() {
|
|
|
136 auto now = _now();
|
|
|
137 double ret = _query(now);
|
|
|
138 _start(now);
|
|
|
139 return ret;
|
|
|
140 }
|
|
|
141 pfc::string8 queryString(unsigned precision = 3) const {
|
|
|
142 return pfc::format_time_ex(query(), precision).get_ptr();
|
|
|
143 }
|
|
|
144 static media_timer create_and_start() {
|
|
|
145 media_timer t; t.start(); return t;
|
|
|
146 }
|
|
|
147 private:
|
|
|
148 void _start(val_t t) { m_start = t; }
|
|
|
149 double _query(val_t t) const { return (t - m_start) / 1000.0; }
|
|
|
150 val_t m_start = 0;
|
|
|
151 };
|
|
|
152 }
|
|
|
153 #else // not _WIN32
|
|
|
154
|
|
|
155 namespace pfc {
|
|
|
156
|
|
|
157 class hires_timer {
|
|
|
158 public:
|
|
|
159 hires_timer() : m_start() {}
|
|
|
160 void start();
|
|
|
161 double query() const;
|
|
|
162 double query_reset();
|
|
|
163 pfc::string8 queryString(unsigned precision = 3) const;
|
|
|
164
|
|
|
165 static hires_timer create_and_start() {
|
|
|
166 hires_timer t; t.start(); return t;
|
|
|
167 }
|
|
|
168 private:
|
|
|
169 double m_start;
|
|
|
170 };
|
|
|
171
|
|
|
172 typedef hires_timer lores_timer;
|
|
|
173 typedef hires_timer media_timer;
|
|
|
174
|
|
|
175 }
|
|
|
176
|
|
|
177 #endif // _WIN32
|
|
|
178
|
|
|
179 #ifndef _WIN32
|
|
|
180 struct timespec;
|
|
|
181 #endif
|
|
|
182
|
|
|
183 namespace pfc {
|
|
|
184 uint64_t fileTimeWtoU(uint64_t ft);
|
|
|
185 uint64_t fileTimeUtoW(uint64_t ft);
|
|
|
186 #ifndef _WIN32
|
|
|
187 uint64_t fileTimeUtoW( timespec const & ts );
|
|
|
188 #endif
|
|
|
189 uint64_t fileTimeNow();
|
|
|
190 }
|