1 ///////////////////////////////////////////////////////////////////////////////
2 // $Source: x:/prj/tech/libsrc/lg/RCS/timings.h $
4 // $Date: 1998/05/22 14:17:32 $
11 ///////////////////////////////////////////////////////////////////////////////
13 // Performance Timing Classes
14 // ==========================
18 // There are two kinds of timer class:
20 // Diff: Low precision point-to-point timing...
22 // how long since start
23 // how long since last
24 // how long since last
28 // stop, how long since start
30 // Average: Timing of loop or multiple-use code from outside...
34 // stop, what's average?
39 // The classes here may be used directly, but macros are provided for
40 // convenience and quick enable/disable.
45 // While the classes cDiffTimer and cAverageTimer may be used
46 // directly, the accepted usage is through macros for conditional
47 // compilation on PROFILE_ON:
49 // DECLARE_TIMER(name, kind)
51 // where kind is Diff or Average.
55 // DECLARE_TIMER(MyTimer, Average);
56 // TIMER_Start(MyTimer);
59 // TIMER_Mark(MyTimer);
60 // if (TodayIsWednesday())
63 // TIMER_Stop_(MyTimer, "Done example timer");
65 // If PROFILE_ON is defined, this declares a timer with the identifier
66 // name, sets the name string. Use the timer class instance.
68 // A special macro/class combination provides automatic average
71 // DECLARE_AUTO_TIMER(name)
73 // If PROFILE_ON is not defined, this declares nothing
79 // DECLARE_AUTO_TIMER(FooTimer);
86 // A timer set is a (suprise) collection of timers. While the
87 // cPerformanceTimerSet template can be used directly, the
88 // accepted usage is through macros for conditional compilation
91 // DECLARE_TSET(name, kind, number)
95 // DECLARE_TSET(MySet, Average, 3);
96 // TSET_ItemStart(MySet, 2);
99 // TSET_ItemMark(MySet, 2);
100 // if (TodayIsWednesday())
103 // TSET_ItemStop_(MySet, 2, "Done example timer");
105 // --------------------------------------------
106 // @Note (toml 07-01-97): To add: 1) verbosity levels, 2) global clear, enable, quiet
110 ///////////////////////////////////////////////////////////////////////////////
116 EXTERN
unsigned long __declspec(dllimport
) __stdcall
timeGetTime(void);
117 #define TimerRawTimeValue() timeGetTime()
119 #define TimerRawTimeValue() 1L
122 ///////////////////////////////////////////////////////////////////////////////
125 #pragma message ("Profiling enabled...")
127 #define DECLARE_TIMER(name, kind) \
128 static c##kind##Timer name ( #name )
130 #define DECLARE_TSET(name, kind, number) \
131 static cTimerSet < c##kind##Timer , number > name (#kind " timer set " #name)
133 #define DECLARE_AUTO_TIMER(name) \
134 static cAverageTimer name ( #name ); \
135 cAverageTimerMarker name##Marker (name)
137 #define AUTO_TIMER(timer) cAverageTimerMarker timer##Marker (timer)
139 #define TIMER_SetName(timer, name) timer.SetName(name)
140 #define TIMER_GetName(timer) timer.GetName()
141 #define TIMER_IsActive(timer) timer.IsActive()
142 #define TIMER_GetResult(timer) timer.GetResult()
143 #define TIMER_OutputResult(timer) timer.OutputResult()
144 #define TIMER_Clear(timer) timer.Clear()
145 #define TIMER_Start(timer) timer.Start()
146 #define TIMER_Mark(timer) timer.Mark()
147 #define TIMER_Mark_(timer, comment) timer.Mark(comment)
148 #define TIMER_Stop(timer) timer.Stop()
149 #define TIMER_Stop_(timer, comment) timer.Stop(comment)
150 #define TIMER_MarkStop(timer) timer.MarkStop()
151 #define TIMER_MarkStop_(timer, comment) timer.MarkStop(comment)
153 #define TSET_SetName(set, name) set.SetName(name)
154 #define TSET_GetName(set) set.GetName()
155 #define TSET_Size(set) set.Size()
156 #define TSET_StopAll(set) set.StopAll()
157 #define TSET_ClearAll(set) set.ClearAll()
158 #define TSET_OutputResultAll(set) set.OutputResultAll()
159 #define TSET_GetSumResult() set.GetSumResult()
160 #define TSET_OutputSumResult() set.OutputSumResult()
161 #define TSET_TimerSetName(set, timer, name) set[timer].SetName(name)
162 #define TSET_TimerGetName(set, timer) set[timer].GetName()
163 #define TSET_TimerIsActive(set, timer) set[timer].IsActive()
164 #define TSET_TimerGetResult(set, timer) set[timer].GetResult()
165 #define TSET_TimerOutputResult(set, timer) set[timer].OutputResult()
166 #define TSET_TimerClear(set, timer) set[timer].Clear()
167 #define TSET_TimerStart(set, timer) set[timer].Start()
168 #define TSET_TimerMark(set, timer) set[timer].Mark()
169 #define TSET_TimerMark_(set, timer, comment) set[timer].Mark(comment)
170 #define TSET_TimerStop(set, timer) set[timer].Stop()
171 #define TSET_TimerStop_(set, timer, comment) set[timer].Stop(comment)
172 #define TSET_TimerMarkStop(set, timer) set[timer].MarkStop()
173 #define TSET_TimerMarkStop_(set, timer, comment) set[timer].MarkStop(comment)
177 #define DECLARE_TIMER(name, kind)
178 #define DECLARE_TSET(name, kind, number)
179 #define DECLARE_AUTO_TIMER(name)
181 #define AUTO_TIMER(timer)
183 #define TIMER_SetName(timer, name)
184 #define TIMER_GetName(timer) ""
185 #define TIMER_IsActive(timer) FALSE
186 #define TIMER_GetResult(timer) (-1.0)
187 #define TIMER_OutputResult(timer)
188 #define TIMER_Clear(timer)
189 #define TIMER_Start(timer)
190 #define TIMER_Mark(timer)
191 #define TIMER_Mark_(timer, comment)
192 #define TIMER_Stop(timer)
193 #define TIMER_Stop_(timer, comment)
194 #define TIMER_MarkStop(timer)
195 #define TIMER_MarkStop_(timer, comment)
197 #define TSET_SetName(set, name)
198 #define TSET_GetName(set) ""
199 #define TSET_Size(set) 0
200 #define TSET_StopAll(set)
201 #define TSET_ClearAll(set)
202 #define TSET_TimerGetResult(set, timer) (-1.0)
203 #define TSET_OutputResultAll(set)
204 #define TSET_GetSumResult() (-1.0)
205 #define TSET_OutputSumResult()
206 #define TSET_TimerSetName(set, timer, name)
207 #define TSET_TimerGetName(set, timer) ""
208 #define TSET_TimerIsActive(set, timer) FALSE
209 #define TSET_TimerOutputResult(set, timer)
210 #define TSET_TimerClear(set, timer)
211 #define TSET_TimerStart(set, timer)
212 #define TSET_TimerMark(set, timer)
213 #define TSET_TimerMark_(set, timer, comment)
214 #define TSET_TimerStop(set, timer)
215 #define TSET_TimerStop_(set, timer, comment)
216 #define TSET_TimerMarkStop(set, timer)
217 #define TSET_TimerMarkStop_(set, timer, comment)
223 ///////////////////////////////////////////////////////////////////////////////
231 void SetName(const char * p
);
232 const char * GetName() const;
233 BOOL
IsActive() const;
237 cTimerBase(const char * p
);
248 ///////////////////////////////////////////////////////////////////////////////
250 // CLASS: cSimpleTimer
253 class cSimpleTimer
: public cTimerBase
257 cSimpleTimer(const char * p
);
268 unsigned long m_StartTime
;
269 unsigned long m_TotalTime
;
272 ///////////////////////////////////////////////////////////////////////////////
277 class cDiffTimer
: public cTimerBase
281 cDiffTimer(const char * p
);
291 void Mark(const char * pcszComment
);
293 void Stop(); // output status
294 void Stop(const char * pcszComment
);
297 unsigned long m_StartTime
;
298 unsigned long m_LastTime
;
301 ///////////////////////////////////////////////////////////////////////////////
303 // CLASS: cAverageTimer
306 class cAverageTimer
: public cTimerBase
310 cAverageTimer(const char * p
);
314 ulong
GetTotalTime();
327 void Stop(const char * pcszComment
);
330 void MarkStop(const char * pcszComment
);
333 unsigned long m_StartTime
;
334 unsigned long m_TotalTime
;
335 unsigned long m_Iterations
;
336 unsigned long m_Depth
;
337 unsigned long m_MinTime
;
338 unsigned long m_MaxTime
;
341 ///////////////////////////////////////////////////////////////////////////////
343 // CLASS: cAverageTimerMarker
346 class cAverageTimerMarker
349 cAverageTimerMarker(cAverageTimer
&);
350 ~cAverageTimerMarker();
353 cAverageTimer
& m_AverageTimer
;
356 ///////////////////////////////////////////////////////////////////////////////
361 template <class TIMER_TYPE
, int SIZE
>
366 cTimerSet(const char *);
371 void SetName(const char * p
);
372 const char * GetName() const;
374 TIMER_TYPE
& operator[](int i
);
378 void OutputResultAll();
380 double GetSumResult();
381 void OutputSumResult();
384 TIMER_TYPE m_PerformanceTimers
[SIZE
];
388 ///////////////////////////////////////
391 class cDiffTimerSet
: public cTimerSet
<cDiffTimer
, SIZE
>
395 ///////////////////////////////////////
398 class cAverageTimerSet
: public cTimerSet
<cAverageTimer
, SIZE
>
402 ///////////////////////////////////////////////////////////////////////////////
404 // CLASS: cTimerBase, inline functions
407 inline void cTimerBase::SetName(const char * p
)
409 strncpy(m_szName
, p
, sizeof(m_szName
)-1);
410 m_szName
[sizeof(m_szName
)-1] = 0;
413 ///////////////////////////////////////
415 inline const char * cTimerBase::GetName() const
420 ///////////////////////////////////////
422 inline BOOL
cTimerBase::IsActive() const
424 return m_flags
& kActive
;
427 ///////////////////////////////////////
429 inline cTimerBase::cTimerBase()
435 ///////////////////////////////////////
437 inline cTimerBase::cTimerBase(const char * p
)
443 ///////////////////////////////////////////////////////////////////////////////
445 // CLASS: cSimpleTimer, inline functions
448 inline cSimpleTimer::cSimpleTimer()
453 ///////////////////////////////////////
455 inline cSimpleTimer::cSimpleTimer(const char * p
)
456 : cTimerBase(p
), m_TotalTime(0)
460 ///////////////////////////////////////
462 inline double cSimpleTimer::GetResult()
464 if (m_TotalTime
&& !IsActive())
465 return (double)(m_TotalTime
);
469 ///////////////////////////////////////
471 void SimpleTimerOutputResult(const char *, ulong
);
473 inline void cSimpleTimer::OutputResult()
475 if (m_TotalTime
&& !IsActive())
476 SimpleTimerOutputResult(m_szName
, m_TotalTime
);
477 mprintf("Total time for %s: %lu ms\n", m_szName
, m_TotalTime
);
480 ///////////////////////////////////////
482 inline void cSimpleTimer::Clear()
484 m_flags
&= ~cTimerBase::kActive
;
488 ///////////////////////////////////////
490 inline void cSimpleTimer::Start()
492 m_flags
|= cTimerBase::kActive
;
493 m_StartTime
= TimerRawTimeValue();
496 ///////////////////////////////////////
498 inline void cSimpleTimer::Stop()
500 unsigned long MarkTime
= TimerRawTimeValue();
501 m_TotalTime
+= MarkTime
- m_StartTime
;
502 m_flags
&= ~cTimerBase::kActive
;
505 ///////////////////////////////////////
507 inline cSimpleTimer::~cSimpleTimer()
516 ///////////////////////////////////////////////////////////////////////////////
518 // CLASS: cDiffTimer, inline functions
521 inline cDiffTimer::cDiffTimer()
526 ///////////////////////////////////////
528 inline cDiffTimer::cDiffTimer(const char * p
)
529 : cTimerBase(p
), m_LastTime(0)
533 ///////////////////////////////////////
535 inline double cDiffTimer::GetResult()
537 if (m_LastTime
&& !IsActive())
538 return (double)(m_LastTime
- m_StartTime
);
542 ///////////////////////////////////////
544 void DiffTimerOutputResult(const char *, ulong
);
546 inline void cDiffTimer::OutputResult()
548 if (m_LastTime
&& !IsActive())
549 DiffTimerOutputResult(m_szName
, m_LastTime
- m_StartTime
);
552 ///////////////////////////////////////
554 inline void cDiffTimer::Clear()
556 m_flags
&= ~cTimerBase::kActive
;
560 ///////////////////////////////////////
562 inline void cDiffTimer::Start()
564 m_flags
|= cTimerBase::kActive
;
565 m_StartTime
= m_LastTime
= TimerRawTimeValue();
568 ///////////////////////////////////////
570 inline void cDiffTimer::Mark()
572 unsigned long MarkTime
= TimerRawTimeValue();
573 mprintf("%s: Time elapsed %lu ms (%lu ms)\n", m_szName
, MarkTime
- m_LastTime
, MarkTime
- m_StartTime
);
574 m_LastTime
= TimerRawTimeValue();
577 ///////////////////////////////////////
579 inline void cDiffTimer::Mark(const char * pcszComment
)
581 unsigned long MarkTime
= TimerRawTimeValue();
582 mprintf("%s: Time elapsed %lu ms (%lu ms); (%s)\n", m_szName
, MarkTime
- m_LastTime
, MarkTime
- m_StartTime
, pcszComment
);
583 m_LastTime
= TimerRawTimeValue();
586 ///////////////////////////////////////
588 inline void cDiffTimer::Stop()
590 unsigned long MarkTime
= TimerRawTimeValue();
591 mprintf("Stop %s: Time elapsed %lu ms (%lu ms)\n", m_szName
, MarkTime
- m_LastTime
, MarkTime
- m_StartTime
);
592 m_LastTime
= MarkTime
;
593 m_flags
&= ~cTimerBase::kActive
;
596 ///////////////////////////////////////
598 inline void cDiffTimer::Stop(const char * pcszComment
)
600 unsigned long MarkTime
= TimerRawTimeValue();
601 mprintf("Stop %s: Time elapsed %lu ms (%lu ms); (%s)\n", m_szName
, MarkTime
- m_LastTime
, MarkTime
- m_StartTime
, pcszComment
);
602 m_LastTime
= MarkTime
;
603 m_flags
&= ~cTimerBase::kActive
;
606 ///////////////////////////////////////
608 inline cDiffTimer::~cDiffTimer()
617 ///////////////////////////////////////////////////////////////////////////////
619 // CLASS: cAverageTimer, inline functions
622 inline cAverageTimer::cAverageTimer()
623 : m_StartTime(0L), m_TotalTime(0L), m_Iterations(0L), m_Depth(0), m_MinTime(0xffffffffL
), m_MaxTime(0L)
627 ///////////////////////////////////////
629 inline cAverageTimer::cAverageTimer(const char * p
)
630 : cTimerBase(p
), m_StartTime(0L), m_TotalTime(0L), m_Iterations(0L), m_Depth(0), m_MinTime(0xffffffffL
), m_MaxTime(0L)
634 ///////////////////////////////////////
636 inline ulong
cAverageTimer::GetIters()
641 ///////////////////////////////////////
643 inline ulong
cAverageTimer::GetTotalTime()
648 ///////////////////////////////////////
650 inline ulong
cAverageTimer::GetMinTime()
655 ///////////////////////////////////////
657 inline ulong
cAverageTimer::GetMaxTime()
662 ///////////////////////////////////////
664 inline double cAverageTimer::GetResult()
666 if (m_Iterations
&& !IsActive())
667 return double(m_TotalTime
)/double(m_Iterations
);
671 ///////////////////////////////////////
673 void AverageTimerOutputResult(const char *, double, ulong
, ulong
, ulong
, ulong
);
675 inline void cAverageTimer::OutputResult()
677 if (m_Iterations
&& !IsActive())
678 AverageTimerOutputResult(m_szName
, double(m_TotalTime
)/double(m_Iterations
), m_MaxTime
, m_MinTime
, m_TotalTime
, m_Iterations
);
681 ///////////////////////////////////////
683 inline void cAverageTimer::Clear()
688 m_MinTime
= 0xffffffffL
;
692 ///////////////////////////////////////
694 inline void cAverageTimer::Start()
699 m_flags
|= cTimerBase::kActive
;
700 m_StartTime
= TimerRawTimeValue();
704 ///////////////////////////////////////
706 inline void cAverageTimer::Mark()
711 ///////////////////////////////////////
713 inline void cAverageTimer::Stop()
718 unsigned long delta
=TimerRawTimeValue()-m_StartTime
;
719 m_TotalTime
+= delta
;
720 if(delta
>m_MaxTime
) m_MaxTime
=delta
;
721 if(delta
<m_MinTime
) m_MinTime
=delta
;
722 m_flags
&= ~cTimerBase::kActive
;
726 ///////////////////////////////////////
728 inline void cAverageTimer::Stop(const char * pcszComment
)
731 mprintf("Stop %s (%s)\n", m_szName
, pcszComment
);
734 ///////////////////////////////////////
736 inline void cAverageTimer::MarkStop()
742 ///////////////////////////////////////
744 inline void cAverageTimer::MarkStop(const char * pcszComment
)
750 ///////////////////////////////////////
752 inline cAverageTimer::~cAverageTimer()
760 ///////////////////////////////////////////////////////////////////////////////
762 // CLASS: cAverageTimerMarker
765 inline cAverageTimerMarker::cAverageTimerMarker(cAverageTimer
& timer
)
766 : m_AverageTimer(timer
)
768 m_AverageTimer
.Start();
771 ///////////////////////////////////////
773 inline cAverageTimerMarker::~cAverageTimerMarker()
775 m_AverageTimer
.MarkStop();
778 ///////////////////////////////////////////////////////////////////////////////
780 // CLASS: cTimerSet, inline functions
783 template <class TIMER_TYPE
, int NUM_TIMERS
>
784 inline int cTimerSet
<TIMER_TYPE
, NUM_TIMERS
>::Size() const
789 ///////////////////////////////////////
791 template <class TIMER_TYPE
, int NUM_TIMERS
>
792 inline void cTimerSet
<TIMER_TYPE
, NUM_TIMERS
>::SetName(const char * p
)
794 strncpy(m_szName
, p
, sizeof(m_szName
)-1);
795 m_szName
[sizeof(m_szName
)-1] = 0;
798 ///////////////////////////////////////
800 template <class TIMER_TYPE
, int NUM_TIMERS
>
801 inline const char * cTimerSet
<TIMER_TYPE
, NUM_TIMERS
>::GetName() const
806 ///////////////////////////////////////
808 template <class TIMER_TYPE
, int NUM_TIMERS
>
809 inline TIMER_TYPE
& cTimerSet
<TIMER_TYPE
, NUM_TIMERS
>::operator[](int i
)
811 return m_PerformanceTimers
[i
];
814 ///////////////////////////////////////
816 template <class TIMER_TYPE
, int NUM_TIMERS
>
817 inline void cTimerSet
<TIMER_TYPE
, NUM_TIMERS
>::StopAll()
819 for (int i
= 0; i
< NUM_TIMERS
; i
++)
820 m_PerformanceTimers
[i
].Stop();
823 ///////////////////////////////////////
825 template <class TIMER_TYPE
, int NUM_TIMERS
>
826 inline void cTimerSet
<TIMER_TYPE
, NUM_TIMERS
>::ClearAll()
828 for (int i
= 0; i
< NUM_TIMERS
; i
++)
829 m_PerformanceTimers
[i
].Clear();
832 ///////////////////////////////////////
834 template <class TIMER_TYPE
, int NUM_TIMERS
>
835 inline void cTimerSet
<TIMER_TYPE
, NUM_TIMERS
>::OutputResultAll()
837 for (int i
= 0; i
< NUM_TIMERS
; i
++)
838 m_PerformanceTimers
[i
].OutputResult();
841 ///////////////////////////////////////
843 template <class TIMER_TYPE
, int NUM_TIMERS
>
844 inline double cTimerSet
<TIMER_TYPE
, NUM_TIMERS
>::GetSumResult()
849 for (int i
= 0; i
< NUM_TIMERS
; i
++)
851 result
= m_PerformanceTimers
[i
].GetResult();
859 ///////////////////////////////////////
861 template <class TIMER_TYPE
, int NUM_TIMERS
>
862 inline void cTimerSet
<TIMER_TYPE
, NUM_TIMERS
>::OutputSumResult()
864 double sum
= GetSumResult();
866 mprintf("Sum time for %s: %g ms\n", m_szName
, sum
);
869 ///////////////////////////////////////
871 template <class TIMER_TYPE
, int NUM_TIMERS
>
872 inline cTimerSet
<TIMER_TYPE
, NUM_TIMERS
>::cTimerSet()
874 for (int i
= 0; i
< Size(); i
++)
876 sprintf(m_szName
, "Timer %d", i
);
877 m_PerformanceTimers
[i
].SetName(m_szName
);
882 ///////////////////////////////////////
884 template <class TIMER_TYPE
, int NUM_TIMERS
>
885 inline cTimerSet
<TIMER_TYPE
, NUM_TIMERS
>::cTimerSet(const char * p
)
887 for (int i
= 0; i
< Size(); i
++)
889 sprintf(m_szName
, "%s timer %d", p
, i
);
890 m_PerformanceTimers
[i
].SetName(m_szName
);
895 ///////////////////////////////////////
897 template <class TIMER_TYPE
, int NUM_TIMERS
>
898 inline cTimerSet
<TIMER_TYPE
, NUM_TIMERS
>::~cTimerSet()
903 ///////////////////////////////////////////////////////////////////////////////
906 #endif /* !__TIMINGS_H */