glperformance.h

00001 /*
00002 Copyright (c) 2000-2007 Lee Thomason (www.grinninglizard.com)
00003 Grinning Lizard Utilities.
00004 
00005 This software is provided 'as-is', without any express or implied 
00006 warranty. In no event will the authors be held liable for any 
00007 damages arising from the use of this software.
00008 
00009 Permission is granted to anyone to use this software for any 
00010 purpose, including commercial applications, and to alter it and 
00011 redistribute it freely, subject to the following restrictions:
00012 
00013 1. The origin of this software must not be misrepresented; you must 
00014 not claim that you wrote the original software. If you use this 
00015 software in a product, an acknowledgment in the product documentation 
00016 would be appreciated but is not required.
00017 
00018 2. Altered source versions must be plainly marked as such, and 
00019 must not be misrepresented as being the original software.
00020 
00021 3. This notice may not be removed or altered from any source 
00022 distribution.
00023 */
00024 
00025 
00026 
00027 #ifndef GRINLIZ_PERFORMANCE_MEASURE
00028 #define GRINLIZ_PERFORMANCE_MEASURE
00029 
00030 #ifdef _MSC_VER
00031 #pragma warning( disable : 4530 )
00032 #pragma warning( disable : 4786 )
00033 #endif
00034 
00035 #include "gldebug.h"
00036 #include "gltypes.h"
00037 #include "SDL.h"
00038 
00039 namespace grinliz {
00040 
00041 #ifdef _MSC_VER
00042         inline U64 FastTime()
00043         {
00044                 union 
00045                 {
00046                         U64 result;
00047                         struct
00048                         {
00049                                 U32 lo;
00050                                 U32 hi;
00051                         } split;
00052                 } u;
00053                 u.result = 0;
00054 
00055                 _asm {
00056                         //pushad;       // don't need - aren't using "emit"
00057                         cpuid;          // force all previous instructions to complete - else out of order execution can confuse things
00058                         rdtsc;
00059                         mov u.split.hi, edx;
00060                         mov u.split.lo, eax;
00061                         //popad;
00062                 }                               
00063                 return u.result;
00064         }
00065         #define LILITH_CONVERT_TO_MSEC (10000)
00066 
00067 #else
00068         inline U64 FastTime()
00069         {
00070                 #if defined (__GNUC__) && !defined( __APPLE__ )
00071 
00072                         U64 val;
00073                  __asm__ __volatile__ ("rdtsc" : "=A" (val));
00074                  return val;
00075                         #define LILITH_CONVERT_TO_MSEC (10000)
00076         #else
00077                         return SDL_GetTicks();
00078                         #define LILITH_CONVERT_TO_MSEC (1)
00079                 #endif
00080         }
00081 #endif
00082 
00083 
00084 const int GL_MAX_PROFILE_ITEM = 32;     // Max functions that can be profiled.
00085 
00086 // Static - there is only one of these for a given function.
00087 struct PerformanceData
00088 {
00089         PerformanceData( const char* name, const char* subName );
00090 
00091         const char* name;
00092         const char* subName;
00093         int id;
00094         U32 functionCallsTop;
00095         U64 functionTimeTop;
00096         U32 functionCallsSub;
00097         U64 functionTimeSub;
00098 
00099         void Clear();
00100 };
00101 
00102 
00103 struct ProfileItem
00104 {
00105         const char* name;
00106         U32 functionCalls;      // # of calls
00107         U64 functionTime;       // total time - in no particular unit (multiple of clock cycle)
00108         U32 functionTimeMSec;
00109 };
00110 
00111 struct ProfileData
00112 {
00113         U64 totalTime;          // total time of all items (in CPU clocks)
00114         U32 totalTimeMSec;
00115         U32 count;                      // number of items
00116         grinliz::ProfileItem item[ GL_MAX_PROFILE_ITEM*2 ];
00117 };
00118 
00119 
00131 class Performance
00132 {
00133         friend struct PerformanceData;
00134   public:
00135 
00136         Performance( PerformanceData* _data )   {
00137                 this->data = _data;
00138 
00139                 if ( inUse )
00140                         ++data->functionCallsSub;
00141                 else
00142                         ++data->functionCallsTop;
00143 
00144                 start = FastTime();
00145                 ++inUse;
00146         }
00147 
00148         ~Performance()
00149         {
00150                 --inUse;
00151                 U64 end = FastTime();
00152                 GLASSERT( end >= start );
00153                 if ( inUse )
00154                         data->functionTimeSub += ( end - start );
00155                 else    
00156                         data->functionTimeTop += ( end - start );
00157         }
00158 
00160     static void Dump( FILE* fp, const char* desc );
00162         static const grinliz::ProfileData& GetData( bool sortOnTime );
00164         static void Clear();
00165 
00166   protected:
00167 
00168         static PerformanceData* map[ GL_MAX_PROFILE_ITEM ];
00169         static ProfileData        profile;
00170         static int numMap;
00171         static int inUse;
00172 
00173         PerformanceData* data;
00174         U64 start;
00175 };
00176 
00177 #ifdef L3PERF
00178         #define L3PERFTRACK static PerformanceData data( __FUNCTION__, __FUNCTION__ ); Performance perf( &data );
00179 #else
00180         #define L3PERFTRACK {}
00181 #endif
00182 
00183 
00184 };              
00185 
00186 #endif

Generated on Fri Mar 23 19:36:21 2007 for Lilith3D by  doxygen 1.5.1-p1