AGX Dynamics 2.41.3.2
Loading...
Searching...
No Matches
Timer.h
Go to the documentation of this file.
1/*
2Copyright 2007-2025. Algoryx Simulation AB.
3
4All AGX source code, intellectual property, documentation, sample code,
5tutorials, scene files and technical white papers, are copyrighted, proprietary
6and confidential material of Algoryx Simulation AB. You may not download, read,
7store, distribute, publish, copy or otherwise disseminate, use or expose this
8material unless having a written signed agreement with Algoryx Simulation AB, or having been
9advised so by Algoryx Simulation AB for a time limited evaluation, or having purchased a
10valid commercial license from Algoryx Simulation AB.
11
12Algoryx Simulation AB disclaims all responsibilities for loss or damage caused
13from using this software, unless otherwise stated in written agreements with
14Algoryx Simulation AB.
15*/
16
17#pragma once
18
19#include <agx/agxCore_export.h>
20#include <agx/Integer.h>
21
22#include <agx/agx.h>
23
24#if defined(_MSC_VER)
25#include <intrin.h>
26#pragma intrinsic(__rdtsc)
27#endif
28
29
30#ifdef __APPLE__
31 #include <sys/types.h>
32 #include <sys/sysctl.h>
33 #include <mach/mach_time.h>
34#endif
35
36#ifdef AGX_APPLE_IOS
37#include <mach/mach_time.h>
38#endif
39
40#ifndef _WIN32
41#include <unistd.h>
42#endif
43
44
45
46
47namespace agx {
48
62 {
63 public:
64
70 Timer(bool startImmediately = false);
71
76 void start();
77
83 void stop();
84
88 void reset(bool startAfterReset = false);
89
94 Real64 getTime() const;
95
97 UInt64 getNumTicks() const;
98
100 UInt64 getStartTick() const;
101
103 bool isRunning() const;
104
106 static UInt64 getCurrentTick();
107
108#ifndef SWIG
110 static Real64 getTime( UInt64 startTick );
111#endif
112
114 static Real64 convertToMs( UInt64 ticks );
115
117 static void initClockSpeed();
118
119 private:
120 static agx::Real clockSpeed();
121
122 private:
123 UInt64 m_start;
124 UInt64 m_total;
125 bool m_running;
126
127 static agx::Real s_clockSpeed;
128 };
129
130
131 /* Implementation */
132 inline Timer::Timer(bool startImmediately)
133 {
134 reset();
135 if (startImmediately)
136 this->start();
137 }
138
139
141 {
142 if (m_running)
143 return;
144
145 m_running = true;
146
147 m_start = getCurrentTick();
148 }
149
150
152 {
153 if (m_running) {
154 m_running = false;
155
156 UInt64 now = getCurrentTick();
157 m_total += (now - m_start);
158 }
159 }
160
161
162 AGX_FORCE_INLINE void Timer::reset(bool startAfterReset)
163 {
164 m_start = 0L;
165 m_total = 0L;
166
167 m_running = false;
168 if (startAfterReset)
169 this->start();
170 }
171
172
174 {
175 return m_total;
176 }
177
178
180 {
181 return m_start;
182 }
183
184
186 {
187 return m_running;
188 }
189
190
192 {
193 return m_running ? (clockSpeed() * (Real64)(getCurrentTick() - m_start + m_total)) : clockSpeed() * (Real64)m_total;
194 }
195
196
197 AGX_FORCE_INLINE agx::Real Timer::clockSpeed()
198 {
199 #ifdef AGX_DEBUG
200 agxAssert1(s_clockSpeed >= 0, "Timer class not properly initialized, forgot to call agx::init() ?");
201 #endif
202
203 return s_clockSpeed;
204 }
205
206
208 {
209#if defined(_MSC_VER)
210 const UInt64 retVal = __rdtsc();
211 return retVal;
212#elif defined(AGX_APPLE_IOS) || defined(__APPLE__)
213 return mach_absolute_time();
214#elif (defined(__GNUC__) || defined(__ICC)) && (defined(__i386__) || defined(__x86_64__)) && !defined(HAVE_TICK_COUNTER)
215
216 // "The CPUID instruction serializes the processor pipeline so that all of the preceding
217 // instructions must retire before it begins execution. ... This is thought to provide
218 //a more accurate cycle count on the code being measured." [intel person at forum on intel.com]
219
220 // cpuid writes to eax,ebx,ecx, edx, tell g++ about registers being clobbered
221 // in 64bits ebx is 32bits of the larger rbx register so should not require
222 // any ifdef's in 64bit
223 // would be better to use pushad, cpuid, popad but for some unknown reason gcc
224 // doesn't recognize pushad/popad
225 // Update: gcc has different name for pushad/popad, l postfix instead of d,
226 // but those instructions doesn't work in 64bit
227
228#ifdef __LP64__
229 unsigned long long int lowbits, highbits;
230 __asm__ __volatile__("rdtsc": "=a" (lowbits), "=d"(highbits) : : );
231#else
232 unsigned long int lowbits, highbits;
233 __asm__ __volatile__("pushal\n\t" "cpuid\n\t" "popal\n\t" "rdtsc": "=a" (lowbits), "=d"(highbits) );
234 //__asm__ __volatile__("push %%ebx\n" "push %%ecx\n" "cpuid\n" "rdtsc\n" "pop %%ebx\n" "pop %%ecx": "=a" (lowbits), "=d"(highbits));
235#endif
236
237 return (((unsigned long long int)highbits<<32) | (unsigned long long int)lowbits);
238
239#else
240 agxAbort1("Timer::getCurrentTick failed!");
241 return -1;
242#endif
243
244 }
245
247 {
248 return Timer::convertToMs(Timer::getCurrentTick() - startTick);
249 }
250
252 {
253 return clockSpeed() * (Real64)ticks;
254 }
255
256
257} // namespace agx
#define AGXCORE_EXPORT
The Timer class permits timing execution speed with the same refinement as the built in hardware cloc...
Definition: Timer.h:62
static UInt64 getCurrentTick()
Definition: Timer.h:207
static Real64 convertToMs(UInt64 ticks)
Definition: Timer.h:251
void stop()
Stops the timer.
Definition: Timer.h:151
void start()
Starts the timer.
Definition: Timer.h:140
bool isRunning() const
Definition: Timer.h:185
Real64 getTime() const
Report total elapsed time since start in milliseconds, excluding intervals when the timer was suspend...
Definition: Timer.h:191
UInt64 getNumTicks() const
Report execution time in CPU cycles.
Definition: Timer.h:173
static void initClockSpeed()
For internal use only.
UInt64 getStartTick() const
Definition: Timer.h:179
void reset(bool startAfterReset=false)
Clear all data.
Definition: Timer.h:162
Timer(bool startImmediately=false)
Creates a timer.
Definition: Timer.h:132
#define agxAssert1(expr, msg)
Definition: debug.h:144
#define agxAbort1(msg)
Definition: debug.h:165
#define AGX_FORCE_INLINE
Definition: macros.h:58
The agx namespace contains the dynamics/math part of the AGX Dynamics API.
double Real64
Definition: Real.h:45
uint64_t UInt64
Definition: Integer.h:33
double Real
Definition: Real.h:42
UInt64 AGXCORE_EXPORT getStartTick()