Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/bullet/LinearMath/btQuickprof.h @ 2760

Last change on this file since 2760 was 2662, checked in by rgrieder, 16 years ago

Merged presentation branch back to trunk.

  • Property svn:eol-style set to native
File size: 9.2 KB
Line 
1
2/***************************************************************************************************
3**
4** Real-Time Hierarchical Profiling for Game Programming Gems 3
5**
6** by Greg Hjelstrom & Byon Garrabrant
7**
8***************************************************************************************************/
9
10// Credits: The Clock class was inspired by the Timer classes in
11// Ogre (www.ogre3d.org).
12
13
14
15#ifndef QUICK_PROF_H
16#define QUICK_PROF_H
17
18//To disable built-in profiling, please comment out next line
19//#define BT_NO_PROFILE 1
20#ifndef BT_NO_PROFILE
21
22#include "btScalar.h"
23#include "LinearMath/btAlignedAllocator.h"
24#include <new>
25
26
27
28
29//if you don't need btClock, you can comment next line
30#define USE_BT_CLOCK 1
31
32#ifdef USE_BT_CLOCK
33#ifdef __CELLOS_LV2__
34#include <sys/sys_time.h>
35#include <sys/time_util.h>
36#include <stdio.h>
37#endif
38
39#if defined (SUNOS) || defined (__SUNOS__)
40#include <stdio.h> 
41#endif
42
43#if defined(WIN32) || defined(_WIN32)
44
45#define USE_WINDOWS_TIMERS
46#define WIN32_LEAN_AND_MEAN
47#define NOWINRES
48#define NOMCX
49#define NOIME
50#ifdef _XBOX
51#include <Xtl.h>
52#else
53#include <windows.h>
54#endif
55#include <time.h>
56
57#else
58#include <sys/time.h>
59#endif
60
61#define mymin(a,b) (a > b ? a : b)
62
63///The btClock is a portable basic clock that measures accurate time in seconds, use for profiling.
64class btClock
65{
66public:
67        btClock()
68        {
69#ifdef USE_WINDOWS_TIMERS
70                QueryPerformanceFrequency(&mClockFrequency);
71#endif
72                reset();
73        }
74
75        ~btClock()
76        {
77        }
78
79        /// Resets the initial reference time.
80        void reset()
81        {
82#ifdef USE_WINDOWS_TIMERS
83                QueryPerformanceCounter(&mStartTime);
84                mStartTick = GetTickCount();
85                mPrevElapsedTime = 0;
86#else
87#ifdef __CELLOS_LV2__
88
89                typedef uint64_t  ClockSize;
90                ClockSize newTime;
91                //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
92                SYS_TIMEBASE_GET( newTime );
93                mStartTime = newTime;
94#else
95                gettimeofday(&mStartTime, 0);
96#endif
97
98#endif
99        }
100
101        /// Returns the time in ms since the last call to reset or since
102        /// the btClock was created.
103        unsigned long int getTimeMilliseconds()
104        {
105#ifdef USE_WINDOWS_TIMERS
106                LARGE_INTEGER currentTime;
107                QueryPerformanceCounter(&currentTime);
108                LONGLONG elapsedTime = currentTime.QuadPart - 
109                        mStartTime.QuadPart;
110
111                // Compute the number of millisecond ticks elapsed.
112                unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / 
113                        mClockFrequency.QuadPart);
114
115                // Check for unexpected leaps in the Win32 performance counter. 
116                // (This is caused by unexpected data across the PCI to ISA
117                // bridge, aka south bridge.  See Microsoft KB274323.)
118                unsigned long elapsedTicks = GetTickCount() - mStartTick;
119                signed long msecOff = (signed long)(msecTicks - elapsedTicks);
120                if (msecOff < -100 || msecOff > 100)
121                {
122                        // Adjust the starting time forwards.
123                        LONGLONG msecAdjustment = mymin(msecOff * 
124                                mClockFrequency.QuadPart / 1000, elapsedTime - 
125                                mPrevElapsedTime);
126                        mStartTime.QuadPart += msecAdjustment;
127                        elapsedTime -= msecAdjustment;
128
129                        // Recompute the number of millisecond ticks elapsed.
130                        msecTicks = (unsigned long)(1000 * elapsedTime / 
131                                mClockFrequency.QuadPart);
132                }
133
134                // Store the current elapsed time for adjustments next time.
135                mPrevElapsedTime = elapsedTime;
136
137                return msecTicks;
138#else
139
140#ifdef __CELLOS_LV2__
141                uint64_t freq=sys_time_get_timebase_frequency();
142                double dFreq=((double) freq) / 1000.0;
143                typedef uint64_t  ClockSize;
144                ClockSize newTime;
145                SYS_TIMEBASE_GET( newTime );
146                //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
147
148                return (unsigned long int)((double(newTime-mStartTime)) / dFreq);
149#else
150
151                struct timeval currentTime;
152                gettimeofday(&currentTime, 0);
153                return (currentTime.tv_sec - mStartTime.tv_sec) * 1000 + 
154                        (currentTime.tv_usec - mStartTime.tv_usec) / 1000;
155#endif //__CELLOS_LV2__
156#endif
157        }
158
159        /// Returns the time in us since the last call to reset or since
160        /// the Clock was created.
161        unsigned long int getTimeMicroseconds()
162        {
163#ifdef USE_WINDOWS_TIMERS
164                LARGE_INTEGER currentTime;
165                QueryPerformanceCounter(&currentTime);
166                LONGLONG elapsedTime = currentTime.QuadPart - 
167                        mStartTime.QuadPart;
168
169                // Compute the number of millisecond ticks elapsed.
170                unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / 
171                        mClockFrequency.QuadPart);
172
173                // Check for unexpected leaps in the Win32 performance counter. 
174                // (This is caused by unexpected data across the PCI to ISA
175                // bridge, aka south bridge.  See Microsoft KB274323.)
176                unsigned long elapsedTicks = GetTickCount() - mStartTick;
177                signed long msecOff = (signed long)(msecTicks - elapsedTicks);
178                if (msecOff < -100 || msecOff > 100)
179                {
180                        // Adjust the starting time forwards.
181                        LONGLONG msecAdjustment = mymin(msecOff * 
182                                mClockFrequency.QuadPart / 1000, elapsedTime - 
183                                mPrevElapsedTime);
184                        mStartTime.QuadPart += msecAdjustment;
185                        elapsedTime -= msecAdjustment;
186                }
187
188                // Store the current elapsed time for adjustments next time.
189                mPrevElapsedTime = elapsedTime;
190
191                // Convert to microseconds.
192                unsigned long usecTicks = (unsigned long)(1000000 * elapsedTime / 
193                        mClockFrequency.QuadPart);
194
195                return usecTicks;
196#else
197
198#ifdef __CELLOS_LV2__
199                uint64_t freq=sys_time_get_timebase_frequency();
200                double dFreq=((double) freq)/ 1000000.0;
201                typedef uint64_t  ClockSize;
202                ClockSize newTime;
203                //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
204                SYS_TIMEBASE_GET( newTime );
205
206                return (unsigned long int)((double(newTime-mStartTime)) / dFreq);
207#else
208
209                struct timeval currentTime;
210                gettimeofday(&currentTime, 0);
211                return (currentTime.tv_sec - mStartTime.tv_sec) * 1000000 + 
212                        (currentTime.tv_usec - mStartTime.tv_usec);
213#endif//__CELLOS_LV2__
214#endif
215        }
216
217private:
218#ifdef USE_WINDOWS_TIMERS
219        LARGE_INTEGER mClockFrequency;
220        DWORD mStartTick;
221        LONGLONG mPrevElapsedTime;
222        LARGE_INTEGER mStartTime;
223#else
224#ifdef __CELLOS_LV2__
225        uint64_t        mStartTime;
226#else
227        struct timeval mStartTime;
228#endif
229#endif //__CELLOS_LV2__
230
231};
232
233#endif //USE_BT_CLOCK
234
235
236
237
238///A node in the Profile Hierarchy Tree
239class   CProfileNode {
240
241public:
242        CProfileNode( const char * name, CProfileNode * parent );
243        ~CProfileNode( void );
244
245        CProfileNode * Get_Sub_Node( const char * name );
246
247        CProfileNode * Get_Parent( void )               { return Parent; }
248        CProfileNode * Get_Sibling( void )              { return Sibling; }
249        CProfileNode * Get_Child( void )                        { return Child; }
250
251        void                            CleanupMemory();
252        void                            Reset( void );
253        void                            Call( void );
254        bool                            Return( void );
255
256        const char *    Get_Name( void )                                { return Name; }
257        int                             Get_Total_Calls( void )         { return TotalCalls; }
258        float                           Get_Total_Time( void )          { return TotalTime; }
259
260protected:
261
262        const char *    Name;
263        int                             TotalCalls;
264        float                           TotalTime;
265        unsigned long int                       StartTime;
266        int                             RecursionCounter;
267
268        CProfileNode *  Parent;
269        CProfileNode *  Child;
270        CProfileNode *  Sibling;
271};
272
273///An iterator to navigate through the tree
274class CProfileIterator
275{
276public:
277        // Access all the children of the current parent
278        void                            First(void);
279        void                            Next(void);
280        bool                            Is_Done(void);
281        bool                Is_Root(void) { return (CurrentParent->Get_Parent() == 0); }
282
283        void                            Enter_Child( int index );               // Make the given child the new parent
284        void                            Enter_Largest_Child( void );    // Make the largest child the new parent
285        void                            Enter_Parent( void );                   // Make the current parent's parent the new parent
286
287        // Access the current child
288        const char *    Get_Current_Name( void )                        { return CurrentChild->Get_Name(); }
289        int                             Get_Current_Total_Calls( void ) { return CurrentChild->Get_Total_Calls(); }
290        float                           Get_Current_Total_Time( void )  { return CurrentChild->Get_Total_Time(); }
291
292        // Access the current parent
293        const char *    Get_Current_Parent_Name( void )                 { return CurrentParent->Get_Name(); }
294        int                             Get_Current_Parent_Total_Calls( void )  { return CurrentParent->Get_Total_Calls(); }
295        float                           Get_Current_Parent_Total_Time( void )   { return CurrentParent->Get_Total_Time(); }
296
297protected:
298
299        CProfileNode *  CurrentParent;
300        CProfileNode *  CurrentChild;
301
302        CProfileIterator( CProfileNode * start );
303        friend  class           CProfileManager;
304};
305
306
307///The Manager for the Profile system
308class   CProfileManager {
309public:
310        static  void                                            Start_Profile( const char * name );
311        static  void                                            Stop_Profile( void );
312
313        static  void                                            CleanupMemory(void)
314        {
315                Root.CleanupMemory();
316        }
317
318        static  void                                            Reset( void );
319        static  void                                            Increment_Frame_Counter( void );
320        static  int                                             Get_Frame_Count_Since_Reset( void )             { return FrameCounter; }
321        static  float                                           Get_Time_Since_Reset( void );
322
323        static  CProfileIterator *      Get_Iterator( void )   
324        { 
325               
326                return new CProfileIterator( &Root ); 
327        }
328        static  void                                            Release_Iterator( CProfileIterator * iterator ) { delete ( iterator); }
329
330        static void     dumpRecursive(CProfileIterator* profileIterator, int spacing);
331
332        static void     dumpAll();
333
334private:
335        static  CProfileNode                    Root;
336        static  CProfileNode *                  CurrentNode;
337        static  int                                             FrameCounter;
338        static  unsigned long int                                       ResetTime;
339};
340
341
342///ProfileSampleClass is a simple way to profile a function's scope
343///Use the BT_PROFILE macro at the start of scope to time
344class   CProfileSample {
345public:
346        CProfileSample( const char * name )
347        { 
348                CProfileManager::Start_Profile( name ); 
349        }
350
351        ~CProfileSample( void )                                 
352        { 
353                CProfileManager::Stop_Profile(); 
354        }
355};
356
357
358#define BT_PROFILE( name )                      CProfileSample __profile( name )
359
360#else
361
362#define BT_PROFILE( name )
363
364#endif //#ifndef BT_NO_PROFILE
365
366
367
368#endif //QUICK_PROF_H
369
370
Note: See TracBrowser for help on using the repository browser.