diff --git a/Generals/Code/GameEngine/Include/Common/PerfTimer.h b/Generals/Code/GameEngine/Include/Common/PerfTimer.h index 8f03af506d8..0b88b581394 100644 --- a/Generals/Code/GameEngine/Include/Common/PerfTimer.h +++ b/Generals/Code/GameEngine/Include/Common/PerfTimer.h @@ -85,7 +85,8 @@ __forceinline void GetPrecisionTimer(Int64* t) class PerfGather { public: - PerfGather( const char *identifier ); + // If net only (default), subtract perf timers running inside. [8/12/2003] + PerfGather( const char *identifier, Bool netOnly=true ); virtual ~PerfGather( ); __forceinline void startTimer(); @@ -126,6 +127,7 @@ class PerfGather PerfGather* m_next; PerfGather* m_prev; Bool m_ignore; + Bool m_netTimeOnly; }; //------------------------------------------------------------------------------------------------- @@ -161,7 +163,9 @@ void PerfGather::stopTimer() { // don't add the time it took for us to actually get the ticks (in startTimer) to our parent... (*m_activeHead)->m_runningTimeGross -= (s_stopStartOverhead); - (*m_activeHead)->m_runningTimeNet -= (runTime + s_stopStartOverhead); + if ((*m_activeHead)->m_netTimeOnly) { + (*m_activeHead)->m_runningTimeNet -= (runTime + s_stopStartOverhead); + } } } @@ -224,6 +228,7 @@ AutoPerfGatherIgnore::~AutoPerfGatherIgnore() } //------------------------------------------------------------------------------------------------- +#define DECLARE_TOTAL_PERF_TIMER(id) static PerfGather s_##id(#id, false); #define DECLARE_PERF_TIMER(id) static PerfGather s_##id(#id); #define USE_PERF_TIMER(id) AutoPerfGather a_##id(s_##id); #define IGNORE_PERF_TIMER(id) AutoPerfGatherIgnore a_##id(s_##id); @@ -308,6 +313,7 @@ extern void StatMetricsDisplay( DebugDisplayInterface *dd, void *, FILE *fp ); #else // PERF_TIMERS #define DECLARE_PERF_TIMER(id) + #define DECLARE_TOTAL_PERF_TIMER(id) #define USE_PERF_TIMER(id) #define IGNORE_PERF_TIMER(id) diff --git a/Generals/Code/GameEngine/Include/Common/StackDump.h b/Generals/Code/GameEngine/Include/Common/StackDump.h index 944c029471c..2d11b754b94 100644 --- a/Generals/Code/GameEngine/Include/Common/StackDump.h +++ b/Generals/Code/GameEngine/Include/Common/StackDump.h @@ -26,8 +26,7 @@ #ifndef IG_DEBUG_STACKTRACE #define IG_DEBUG_STACKTRACE 1 -#endif - +#endif // Unsure about this one -ML 3/25/03 #if defined(RTS_DEBUG) || defined(IG_DEBUG_STACKTRACE) // Writes a stackdump (provide a callback : gets called per line) diff --git a/Generals/Code/GameEngine/Source/Common/PerfTimer.cpp b/Generals/Code/GameEngine/Source/Common/PerfTimer.cpp index 48a39364d19..d8d54a41d72 100644 --- a/Generals/Code/GameEngine/Source/Common/PerfTimer.cpp +++ b/Generals/Code/GameEngine/Source/Common/PerfTimer.cpp @@ -35,6 +35,10 @@ #include "GameClient/Display.h" #include "GameClient/GraphDraw.h" +__forceinline void ProfileGetTime(__int64 &t) +{ + t = _rdtsc(); +} //------------------------------------------------------------------------------------------------- @@ -54,63 +58,139 @@ void GetPrecisionTimerTicksPerSec(Int64* t) *t = s_ticksPerSec; } +//Kris: Plugged in Martin's code to optimize timer setup. +#define HOFFESOMMER_REPLACEMENT_CODE + //------------------------------------------------------------------------------------------------- void InitPrecisionTimer() { -#ifdef USE_QPF - QueryPerformanceFrequency((LARGE_INTEGER*)&s_ticksPerSec); +#ifdef HOFFESOMMER_REPLACEMENT_CODE + + // measure clock cycles 3 times for 20 msec each + // then take the 2 counts that are closest, average + _int64 n[ 3 ]; + for( int k = 0; k < 3; k++ ) + { + // wait for end of current tick + unsigned timeEnd = timeGetTime() + 2; + while( timeGetTime() < timeEnd ); //do nothing + + // get cycles + _int64 start, startQPC, endQPC; + QueryPerformanceCounter( (LARGE_INTEGER *)&startQPC ); + ProfileGetTime( start ); + timeEnd += 20; + while( timeGetTime() < timeEnd ); //do nothing + ProfileGetTime( n[ k ] ); + n[ k ] -= start; + + // convert to 1 second + if( QueryPerformanceCounter( (LARGE_INTEGER*)&endQPC ) ) + { + QueryPerformanceFrequency( (LARGE_INTEGER*)&s_ticksPerSec ); + n[ k ] = ( n[ k ] * s_ticksPerSec ) / ( endQPC - startQPC ); + } + else + { + n[ k ] = ( n[ k ] * 1000 ) / 20; + } + } + + // find two closest values + _int64 d01 = n[ 1 ] - n[ 0 ]; + _int64 d02 = n[ 2 ] - n[ 0 ]; + _int64 d12 = n[ 2 ] - n[ 1 ]; + + if( d01 < 0 ) + { + d01 = -d01; + } + if( d02 < 0 ) + { + d02 = -d02; + } + if( d12 < 0 ) + { + d12 = -d12; + } + + _int64 avg; + if( d01 < d02 ) + { + avg = d01 < d12 ? n[ 0 ] + n[ 1 ] : n[ 1 ] + n[ 2 ]; + } + else + { + avg = d02 < d12 ? n[ 0 ] + n[ 2 ] : n[ 1 ] + n[ 2 ]; + } + + //s_ticksPerMSec = 1.0 * TotalTicks / totalTime; + s_ticksPerMSec = avg / 2000.0f; + s_ticksPerSec = s_ticksPerMSec * 1000.0f; + s_ticksPerUSec = s_ticksPerSec / 1000000.0f; + + #else - // Init the precision timers - Int64 totalTime = 0; - Int64 TotalTicks = 0; - static int TESTS = 5; - for (int i = 0; i < TESTS; ++i) - { - int TimeStart; - int TimeStop; - Int64 StartTicks; - Int64 EndTicks; - - TimeStart = timeGetTime(); - GetPrecisionTimer(&StartTicks); - for(;;) + //Kris: With total disrespect, this code costs 5 real seconds of init time + //whenever we fire up the game. + + #ifdef USE_QPF + QueryPerformanceFrequency((LARGE_INTEGER*)&s_ticksPerSec); + #else + // Init the precision timers + Int64 totalTime = 0; + Int64 TotalTicks = 0; + static int TESTS = 5; + + for (int i = 0; i < TESTS; ++i) { - TimeStop = timeGetTime(); - if ((TimeStop - TimeStart) > 1000) + int TimeStart; + int TimeStop; + Int64 StartTicks; + Int64 EndTicks; + + TimeStart = timeGetTime(); + GetPrecisionTimer(&StartTicks); + for(;;) { - GetPrecisionTimer(&EndTicks); - break; + TimeStop = timeGetTime(); + if ((TimeStop - TimeStart) > 1000) + { + GetPrecisionTimer(&EndTicks); + break; + } } - } - TotalTicks += (EndTicks - StartTicks); + TotalTicks += (EndTicks - StartTicks); - totalTime += (TimeStop - TimeStart); - } + totalTime += (TimeStop - TimeStart); + } - s_ticksPerMSec = 1.0 * TotalTicks / totalTime; - s_ticksPerSec = s_ticksPerMSec * 1000.0f; -#endif - s_ticksPerMSec = s_ticksPerSec / 1000.0f; - s_ticksPerUSec = s_ticksPerSec / 1000000.0f; + s_ticksPerMSec = 1.0 * TotalTicks / totalTime; + s_ticksPerSec = s_ticksPerMSec * 1000.0f; + #endif + s_ticksPerMSec = s_ticksPerSec / 1000.0f; + s_ticksPerUSec = s_ticksPerSec / 1000000.0f; + + #ifdef NOT_IN_USE + Int64 bogus[8]; + GetPrecisionTimer(&start); + for (Int ii = 0; ii < ITERS; ++ii) + { + GetPrecisionTimer(&bogus[0]); + GetPrecisionTimer(&bogus[1]); + GetPrecisionTimer(&bogus[2]); + GetPrecisionTimer(&bogus[3]); + GetPrecisionTimer(&bogus[4]); + GetPrecisionTimer(&bogus[5]); + GetPrecisionTimer(&bogus[6]); + GetPrecisionTimer(&bogus[7]); + } + TheTicksToGetTicks = (bogus[7] - start) / (ITERS*8); + DEBUG_LOG(("TheTicksToGetTicks is %d (%f usec)",(int)TheTicksToGetTicks,TheTicksToGetTicks/s_ticksPerUSec)); + #endif -#ifdef NOT_IN_USE - Int64 bogus[8]; - GetPrecisionTimer(&start); - for (Int ii = 0; ii < ITERS; ++ii) - { - GetPrecisionTimer(&bogus[0]); - GetPrecisionTimer(&bogus[1]); - GetPrecisionTimer(&bogus[2]); - GetPrecisionTimer(&bogus[3]); - GetPrecisionTimer(&bogus[4]); - GetPrecisionTimer(&bogus[5]); - GetPrecisionTimer(&bogus[6]); - GetPrecisionTimer(&bogus[7]); - } - TheTicksToGetTicks = (bogus[7] - start) / (ITERS*8); - DEBUG_LOG(("TheTicksToGetTicks is %d (%f usec)",(int)TheTicksToGetTicks,TheTicksToGetTicks/s_ticksPerUSec)); #endif } diff --git a/Generals/Code/GameEngine/Source/Common/System/StackDump.cpp b/Generals/Code/GameEngine/Source/Common/System/StackDump.cpp index f3025de863e..60bc16d6ae1 100644 --- a/Generals/Code/GameEngine/Source/Common/System/StackDump.cpp +++ b/Generals/Code/GameEngine/Source/Common/System/StackDump.cpp @@ -474,6 +474,7 @@ void WriteStackLine(void*address, void (*callback)(const char*)) callback(line); } + //***************************************************************************** //***************************************************************************** void DumpExceptionInfo( unsigned int u, EXCEPTION_POINTERS* e_info )