convert line ends
[canaan.git] / prj / tech / libsrc / lg / timings.h
blobbe2a46ba7a370d09a1155c1a933bb2e10183910f
1 ///////////////////////////////////////////////////////////////////////////////
2 // $Source: x:/prj/tech/libsrc/lg/RCS/timings.h $
3 // $Author: kate $
4 // $Date: 1998/05/22 14:17:32 $
5 // $Revision: 1.8 $
6 //
8 #ifndef __TIMINGS_H
9 #define __TIMINGS_H
11 ///////////////////////////////////////////////////////////////////////////////
13 // Performance Timing Classes
14 // ==========================
16 // KINDS
17 // -----
18 // There are two kinds of timer class:
20 // Diff: Low precision point-to-point timing...
21 // start
22 // how long since start
23 // how long since last
24 // how long since last
25 // .
26 // .
27 // .
28 // stop, how long since start
30 // Average: Timing of loop or multiple-use code from outside...
31 // start
32 // begin loop
33 // mark iteration
34 // stop, what's average?
36 // USAGE
37 // -----
39 // The classes here may be used directly, but macros are provided for
40 // convenience and quick enable/disable.
42 // Single instances
43 // ----------------
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.
53 // Example usage:
54 // //...
55 // DECLARE_TIMER(MyTimer, Average);
56 // TIMER_Start(MyTimer);
57 // for (;;)
58 // {
59 // TIMER_Mark(MyTimer);
60 // if (TodayIsWednesday())
61 // break;
62 // }
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
69 // support:
71 // DECLARE_AUTO_TIMER(name)
73 // If PROFILE_ON is not defined, this declares nothing
75 // Example usage:
76 // //...
77 // foo()
78 // {
79 // DECLARE_AUTO_TIMER(FooTimer);
80 // //...
81 // }
83 // Timer sets
84 // ----------
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
89 // on PROFILE_ON.
91 // DECLARE_TSET(name, kind, number)
93 // Example usage:
94 // //...
95 // DECLARE_TSET(MySet, Average, 3);
96 // TSET_ItemStart(MySet, 2);
97 // for (;;)
98 // {
99 // TSET_ItemMark(MySet, 2);
100 // if (TodayIsWednesday())
101 // break;
102 // }
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 ///////////////////////////////////////////////////////////////////////////////
112 #include <string.h>
113 #include <mprintf.h>
115 #ifdef _WIN32
116 EXTERN unsigned long __declspec(dllimport) __stdcall timeGetTime(void);
117 #define TimerRawTimeValue() timeGetTime()
118 #else
119 #define TimerRawTimeValue() 1L
120 #endif
122 ///////////////////////////////////////////////////////////////////////////////
124 #ifdef PROFILE_ON
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)
175 #else
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)
219 #endif
221 #ifndef SHIP
223 ///////////////////////////////////////////////////////////////////////////////
225 // CLASS: cTimerBase
228 class cTimerBase
230 public:
231 void SetName(const char * p);
232 const char * GetName() const;
233 BOOL IsActive() const;
235 protected:
236 cTimerBase();
237 cTimerBase(const char * p);
239 enum eFlags
241 kActive = 0x01
244 char m_szName[64];
245 BOOL m_flags;
248 ///////////////////////////////////////////////////////////////////////////////
250 // CLASS: cSimpleTimer
253 class cSimpleTimer : public cTimerBase
255 public:
256 cSimpleTimer();
257 cSimpleTimer(const char * p);
258 ~cSimpleTimer();
260 double GetResult();
261 void OutputResult();
263 void Clear();
264 void Start();
265 void Stop();
267 private:
268 unsigned long m_StartTime;
269 unsigned long m_TotalTime;
272 ///////////////////////////////////////////////////////////////////////////////
274 // CLASS: cDiffTimer
277 class cDiffTimer : public cTimerBase
279 public:
280 cDiffTimer();
281 cDiffTimer(const char * p);
282 ~cDiffTimer();
284 double GetResult();
285 void OutputResult();
287 void Clear();
288 void Start();
290 void Mark();
291 void Mark(const char * pcszComment);
293 void Stop(); // output status
294 void Stop(const char * pcszComment);
296 private:
297 unsigned long m_StartTime;
298 unsigned long m_LastTime;
301 ///////////////////////////////////////////////////////////////////////////////
303 // CLASS: cAverageTimer
306 class cAverageTimer : public cTimerBase
308 public:
309 cAverageTimer();
310 cAverageTimer(const char * p);
311 ~cAverageTimer();
313 ulong GetIters();
314 ulong GetTotalTime();
315 ulong GetMinTime();
316 ulong GetMaxTime();
318 double GetResult();
319 void OutputResult();
321 void Clear();
322 void Start();
324 void Mark();
326 void Stop();
327 void Stop(const char * pcszComment);
329 void MarkStop();
330 void MarkStop(const char * pcszComment);
332 private:
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
348 public:
349 cAverageTimerMarker(cAverageTimer &);
350 ~cAverageTimerMarker();
352 private:
353 cAverageTimer & m_AverageTimer;
356 ///////////////////////////////////////////////////////////////////////////////
358 // CLASS: cTimerSet
361 template <class TIMER_TYPE, int SIZE>
362 class cTimerSet
364 public:
365 cTimerSet();
366 cTimerSet(const char *);
367 ~cTimerSet();
369 int Size() const;
371 void SetName(const char * p);
372 const char * GetName() const;
374 TIMER_TYPE & operator[](int i);
376 void StopAll();
377 void ClearAll();
378 void OutputResultAll();
380 double GetSumResult();
381 void OutputSumResult();
383 private:
384 TIMER_TYPE m_PerformanceTimers[SIZE];
385 char m_szName[64];
388 ///////////////////////////////////////
390 template <int SIZE>
391 class cDiffTimerSet : public cTimerSet<cDiffTimer, SIZE>
395 ///////////////////////////////////////
397 template <int SIZE>
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
417 return m_szName;
420 ///////////////////////////////////////
422 inline BOOL cTimerBase::IsActive() const
424 return m_flags & kActive;
427 ///////////////////////////////////////
429 inline cTimerBase::cTimerBase()
430 : m_flags(0)
432 m_szName[0] = 0;
435 ///////////////////////////////////////
437 inline cTimerBase::cTimerBase(const char * p)
438 : m_flags(0)
440 SetName(p);
443 ///////////////////////////////////////////////////////////////////////////////
445 // CLASS: cSimpleTimer, inline functions
448 inline cSimpleTimer::cSimpleTimer()
449 : m_TotalTime(0)
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);
466 return -1.0;
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;
485 m_TotalTime = 0L;
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()
509 if (IsActive())
511 Stop();
512 OutputResult();
516 ///////////////////////////////////////////////////////////////////////////////
518 // CLASS: cDiffTimer, inline functions
521 inline cDiffTimer::cDiffTimer()
522 : m_LastTime(0)
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);
539 return -1.0;
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;
557 m_LastTime = 0L;
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()
610 if (IsActive())
612 Stop();
613 OutputResult();
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()
638 return m_Iterations;
641 ///////////////////////////////////////
643 inline ulong cAverageTimer::GetTotalTime()
645 return m_TotalTime;
648 ///////////////////////////////////////
650 inline ulong cAverageTimer::GetMinTime()
652 return m_MinTime;
655 ///////////////////////////////////////
657 inline ulong cAverageTimer::GetMaxTime()
659 return m_MaxTime;
662 ///////////////////////////////////////
664 inline double cAverageTimer::GetResult()
666 if (m_Iterations && !IsActive())
667 return double(m_TotalTime)/double(m_Iterations);
668 return -1.0;
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()
685 m_flags = 0;
686 m_Iterations = 0L;
687 m_TotalTime = 0L;
688 m_MinTime = 0xffffffffL;
689 m_MaxTime = 0L;
692 ///////////////////////////////////////
694 inline void cAverageTimer::Start()
696 m_Depth++;
697 if (m_Depth == 1)
699 m_flags |= cTimerBase::kActive;
700 m_StartTime = TimerRawTimeValue();
704 ///////////////////////////////////////
706 inline void cAverageTimer::Mark()
708 m_Iterations++;
711 ///////////////////////////////////////
713 inline void cAverageTimer::Stop()
715 m_Depth--;
716 if (m_Depth == 0)
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)
730 Stop();
731 mprintf("Stop %s (%s)\n", m_szName, pcszComment);
734 ///////////////////////////////////////
736 inline void cAverageTimer::MarkStop()
738 Mark();
739 Stop();
742 ///////////////////////////////////////
744 inline void cAverageTimer::MarkStop(const char * pcszComment)
746 Mark();
747 Stop(pcszComment);
750 ///////////////////////////////////////
752 inline cAverageTimer::~cAverageTimer()
754 if (IsActive())
755 Stop();
757 OutputResult();
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
786 return NUM_TIMERS;
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
803 return m_szName;
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()
846 double result;
847 double sum = 0;
849 for (int i = 0; i < NUM_TIMERS; i++)
851 result = m_PerformanceTimers[i].GetResult();
852 if (result < 0)
853 return -1.0;
854 sum += result;
856 return sum;
859 ///////////////////////////////////////
861 template <class TIMER_TYPE, int NUM_TIMERS>
862 inline void cTimerSet<TIMER_TYPE, NUM_TIMERS>::OutputSumResult()
864 double sum = GetSumResult();
865 if (sum > 0)
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);
879 m_szName[0] = 0;
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);
892 SetName(p);
895 ///////////////////////////////////////
897 template <class TIMER_TYPE, int NUM_TIMERS>
898 inline cTimerSet<TIMER_TYPE, NUM_TIMERS>::~cTimerSet()
900 StopAll();
903 ///////////////////////////////////////////////////////////////////////////////
904 #endif /* !SHIP */
906 #endif /* !__TIMINGS_H */