foobar2000 SDK  2015-08-03
timers.h
Go to the documentation of this file.
1 #ifndef _PFC_PROFILER_H_
2 #define _PFC_PROFILER_H_
3 
4 #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
5 
6 #define PFC_HAVE_PROFILER
7 
8 #include <intrin.h>
9 namespace pfc {
11  public:
12  profiler_static(const char * p_name);
14  void add_time(t_int64 delta) { total_time += delta;num_called++; }
15  private:
16  const char * name;
18  };
19 
21  public:
23  owner = p_owner;
24  start = __rdtsc();
25  }
27  t_int64 end = __rdtsc();
28  owner->add_time(end - start);
29  }
30  private:
33  };
34 
35 }
36 #define profiler(name) \
37  static pfc::profiler_static profiler_static_##name(#name); \
38  pfc::profiler_local profiler_local_##name(&profiler_static_##name);
39 
40 
41 #endif
42 
43 #ifdef _WIN32
44 
45 namespace pfc {
46 #if _WIN32_WINNT >= 0x600
47 typedef uint64_t tickcount_t;
48 inline tickcount_t getTickCount() { return GetTickCount64(); }
49 #else
50 #define PFC_TICKCOUNT_32BIT
51 typedef uint32_t tickcount_t;
52 inline tickcount_t getTickCount() { return GetTickCount(); }
53 #endif
54 
55 class hires_timer {
56 public:
57  hires_timer() : m_start() {}
58  void start() {
59  m_start = g_query();
60  }
61  double query() const {
62  return _query( g_query() );
63  }
64  double query_reset() {
65  t_uint64 current = g_query();
66  double ret = _query(current);
67  m_start = current;
68  return ret;
69  }
70  pfc::string8 queryString(unsigned precision = 6) {
71  return pfc::format_time_ex( query(), precision ).get_ptr();
72  }
73 private:
74  double _query(t_uint64 p_val) const {
75  return (double)( p_val - m_start ) / (double) g_query_freq();
76  }
77  static t_uint64 g_query() {
78  LARGE_INTEGER val;
79  if (!QueryPerformanceCounter(&val)) throw pfc::exception_not_implemented();
80  return val.QuadPart;
81  }
83  LARGE_INTEGER val;
84  if (!QueryPerformanceFrequency(&val)) throw pfc::exception_not_implemented();
85  return val.QuadPart;
86  }
88 };
89 
90 class lores_timer {
91 public:
92  lores_timer() : m_start() {}
93  void start() {
94  _start(getTickCount());
95  }
96 
97  double query() const {
98  return _query(getTickCount());
99  }
100  double query_reset() {
101  tickcount_t time = getTickCount();
102  double ret = _query(time);
103  _start(time);
104  return ret;
105  }
106  pfc::string8 queryString(unsigned precision = 3) {
107  return pfc::format_time_ex( query(), precision ).get_ptr();
108  }
109 private:
110  void _start(tickcount_t p_time) {
111 #ifdef PFC_TICKCOUNT_32BIT
112  m_last_seen = p_time;
113 #endif
114  m_start = p_time;
115  }
116  double _query(tickcount_t p_time) const {
117 #ifdef PFC_TICKCOUNT_32BIT
118  t_uint64 time = p_time;
119  if (time < (m_last_seen & 0xFFFFFFFF)) time += 0x100000000;
120  m_last_seen = (m_last_seen & 0xFFFFFFFF00000000) + time;
121  return (double)(m_last_seen - m_start) / 1000.0;
122 #else
123  return (double)(p_time - m_start) / 1000.0;
124 #endif
125  }
127 #ifdef PFC_TICKCOUNT_32BIT
129 #endif
130 };
131 }
132 #else // not _WIN32
133 
134 namespace pfc {
135 
136 class hires_timer {
137 public:
138  hires_timer() : m_start() {}
139  void start();
140  double query() const;
141  double query_reset();
142  pfc::string8 queryString(unsigned precision = 3);
143 private:
144  double m_start;
145 };
146 
148 
149 }
150 
151 #endif // _WIN32
152 
153 #ifndef _WIN32
154 struct timespec;
155 #endif
156 
157 namespace pfc {
158  uint64_t fileTimeWtoU(uint64_t ft);
159  uint64_t fileTimeUtoW(uint64_t ft);
160 #ifndef _WIN32
161  uint64_t fileTimeUtoW( timespec const & ts );
162 #endif
163  uint64_t fileTimeNow();
164 }
165 
166 #endif
double _query(tickcount_t p_time) const
Definition: timers.h:116
pfc::string8 queryString(unsigned precision=3)
Definition: timers.h:106
void _start(tickcount_t p_time)
Definition: timers.h:110
const char * name
Definition: timers.h:16
tickcount_t getTickCount()
Definition: timers.h:48
void start()
Definition: timers.h:93
uint64_t t_uint64
Definition: int_types.h:3
t_uint64 m_last_seen
Definition: timers.h:128
pfc::string8 queryString(unsigned precision=6)
Definition: timers.h:70
double query_reset()
Definition: timers.h:100
double m_start
Definition: timers.h:144
profiler_static * owner
Definition: timers.h:32
const char * get_ptr() const
Definition: string_base.h:492
double query() const
Definition: timers.h:61
double query_reset()
Definition: timers.h:64
uint64_t fileTimeUtoW(uint64_t ft)
Definition: timers.cpp:56
t_uint64 m_start
Definition: timers.h:126
double _query(t_uint64 p_val) const
Definition: timers.h:74
t_uint64 m_start
Definition: timers.h:87
hires_timer lores_timer
Definition: timers.h:147
t_uint64 total_time
Definition: timers.h:17
static t_uint64 g_query()
Definition: timers.h:77
uint64_t fileTimeNow()
Definition: timers.cpp:66
double query() const
Definition: timers.h:97
static t_uint64 g_query_freq()
Definition: timers.h:82
uint64_t tickcount_t
Definition: timers.h:47
void start()
Definition: timers.h:58
profiler_local(profiler_static *p_owner)
Definition: timers.h:22
t_uint64 num_called
Definition: timers.h:17
t_int64 start
Definition: timers.h:31
void add_time(t_int64 delta)
Definition: timers.h:14
uint64_t fileTimeWtoU(uint64_t ft)
Definition: timers.cpp:53
profiler_static(const char *p_name)
Definition: timers.cpp:7
int64_t t_int64
Definition: int_types.h:2