aboutsummaryrefslogtreecommitdiff
path: root/mp/src/public/tier0/fasttimer.h
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /mp/src/public/tier0/fasttimer.h
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/public/tier0/fasttimer.h')
-rw-r--r--mp/src/public/tier0/fasttimer.h1142
1 files changed, 571 insertions, 571 deletions
diff --git a/mp/src/public/tier0/fasttimer.h b/mp/src/public/tier0/fasttimer.h
index e9833b29..0f49a43e 100644
--- a/mp/src/public/tier0/fasttimer.h
+++ b/mp/src/public/tier0/fasttimer.h
@@ -1,571 +1,571 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef FASTTIMER_H
-#define FASTTIMER_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#ifdef _WIN32
-#include <intrin.h>
-#endif
-
-#include <assert.h>
-#include "tier0/platform.h"
-
-PLATFORM_INTERFACE uint64 g_ClockSpeed;
-#if defined( _X360 ) && defined( _CERT )
-PLATFORM_INTERFACE unsigned long g_dwFakeFastCounter;
-#endif
-
-PLATFORM_INTERFACE double g_ClockSpeedMicrosecondsMultiplier;
-PLATFORM_INTERFACE double g_ClockSpeedMillisecondsMultiplier;
-PLATFORM_INTERFACE double g_ClockSpeedSecondsMultiplier;
-
-class CCycleCount
-{
-friend class CFastTimer;
-
-public:
- CCycleCount();
- CCycleCount( uint64 cycles );
-
- void Sample(); // Sample the clock. This takes about 34 clocks to execute (or 26,000 calls per millisecond on a P900).
-
- void Init(); // Set to zero.
- void Init( float initTimeMsec );
- void Init( double initTimeMsec ) { Init( (float)initTimeMsec ); }
- void Init( uint64 cycles );
- bool IsLessThan( CCycleCount const &other ) const; // Compare two counts.
-
- // Convert to other time representations. These functions are slow, so it's preferable to call them
- // during display rather than inside a timing block.
- unsigned long GetCycles() const;
- uint64 GetLongCycles() const;
-
- unsigned long GetMicroseconds() const;
- uint64 GetUlMicroseconds() const;
- double GetMicrosecondsF() const;
- void SetMicroseconds( unsigned long nMicroseconds );
-
- unsigned long GetMilliseconds() const;
- double GetMillisecondsF() const;
-
- double GetSeconds() const;
-
- CCycleCount& operator+=( CCycleCount const &other );
-
- // dest = rSrc1 + rSrc2
- static void Add( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest ); // Add two samples together.
-
- // dest = rSrc1 - rSrc2
- static void Sub( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest ); // Add two samples together.
-
- static uint64 GetTimestamp();
-
- uint64 m_Int64;
-};
-
-class PLATFORM_CLASS CClockSpeedInit
-{
-public:
- CClockSpeedInit()
- {
- Init();
- }
-
- static void Init();
-};
-
-class CFastTimer
-{
-public:
- // These functions are fast to call and should be called from your sampling code.
- void Start();
- void End();
-
- const CCycleCount & GetDuration() const; // Get the elapsed time between Start and End calls.
- CCycleCount GetDurationInProgress() const; // Call without ending. Not that cheap.
-
- // Return number of cycles per second on this processor.
- static inline int64 GetClockSpeed();
-
-private:
- CCycleCount m_Duration;
-#ifdef DEBUG_FASTTIMER
- bool m_bRunning; // Are we currently running?
-#endif
-};
-
-
-// This is a helper class that times whatever block of code it's in
-class CTimeScope
-{
-public:
- CTimeScope( CFastTimer *pTimer );
- ~CTimeScope();
-
-private:
- CFastTimer *m_pTimer;
-};
-
-inline CTimeScope::CTimeScope( CFastTimer *pTotal )
-{
- m_pTimer = pTotal;
- m_pTimer->Start();
-}
-
-inline CTimeScope::~CTimeScope()
-{
- m_pTimer->End();
-}
-
-// This is a helper class that times whatever block of code it's in and
-// adds the total (int microseconds) to a global counter.
-class CTimeAdder
-{
-public:
- CTimeAdder( CCycleCount *pTotal );
- ~CTimeAdder();
-
- void End();
-
-private:
- CCycleCount *m_pTotal;
- CFastTimer m_Timer;
-};
-
-inline CTimeAdder::CTimeAdder( CCycleCount *pTotal )
-{
- m_pTotal = pTotal;
- m_Timer.Start();
-}
-
-inline CTimeAdder::~CTimeAdder()
-{
- End();
-}
-
-inline void CTimeAdder::End()
-{
- if( m_pTotal )
- {
- m_Timer.End();
- *m_pTotal += m_Timer.GetDuration();
- m_pTotal = 0;
- }
-}
-
-
-
-// -------------------------------------------------------------------------- //
-// Simple tool to support timing a block of code, and reporting the results on
-// program exit or at each iteration
-//
-// Macros used because dbg.h uses this header, thus Msg() is unavailable
-// -------------------------------------------------------------------------- //
-
-#define PROFILE_SCOPE(name) \
- class C##name##ACC : public CAverageCycleCounter \
- { \
- public: \
- ~C##name##ACC() \
- { \
- Msg("%-48s: %6.3f avg (%8.1f total, %7.3f peak, %5d iters)\n", \
- #name, \
- GetAverageMilliseconds(), \
- GetTotalMilliseconds(), \
- GetPeakMilliseconds(), \
- GetIters() ); \
- } \
- }; \
- static C##name##ACC name##_ACC; \
- CAverageTimeMarker name##_ATM( &name##_ACC )
-
-#define TIME_SCOPE(name) \
- class CTimeScopeMsg_##name \
- { \
- public: \
- CTimeScopeMsg_##name() { m_Timer.Start(); } \
- ~CTimeScopeMsg_##name() \
- { \
- m_Timer.End(); \
- Msg( #name "time: %.4fms\n", m_Timer.GetDuration().GetMillisecondsF() ); \
- } \
- private: \
- CFastTimer m_Timer; \
- } name##_TSM;
-
-
-// -------------------------------------------------------------------------- //
-
-class CAverageCycleCounter
-{
-public:
- CAverageCycleCounter();
-
- void Init();
- void MarkIter( const CCycleCount &duration );
-
- unsigned GetIters() const;
-
- double GetAverageMilliseconds() const;
- double GetTotalMilliseconds() const;
- double GetPeakMilliseconds() const;
-
-private:
- unsigned m_nIters;
- CCycleCount m_Total;
- CCycleCount m_Peak;
- bool m_fReport;
- const tchar *m_pszName;
-};
-
-// -------------------------------------------------------------------------- //
-
-class CAverageTimeMarker
-{
-public:
- CAverageTimeMarker( CAverageCycleCounter *pCounter );
- ~CAverageTimeMarker();
-
-private:
- CAverageCycleCounter *m_pCounter;
- CFastTimer m_Timer;
-};
-
-
-// -------------------------------------------------------------------------- //
-// CCycleCount inlines.
-// -------------------------------------------------------------------------- //
-
-inline CCycleCount::CCycleCount()
-{
- Init( (uint64)0 );
-}
-
-inline CCycleCount::CCycleCount( uint64 cycles )
-{
- Init( cycles );
-}
-
-inline void CCycleCount::Init()
-{
- Init( (uint64)0 );
-}
-
-inline void CCycleCount::Init( float initTimeMsec )
-{
- if ( g_ClockSpeedMillisecondsMultiplier > 0 )
- Init( (uint64)(initTimeMsec / g_ClockSpeedMillisecondsMultiplier) );
- else
- Init( (uint64)0 );
-}
-
-inline void CCycleCount::Init( uint64 cycles )
-{
- m_Int64 = cycles;
-}
-
-inline void CCycleCount::Sample()
-{
- m_Int64 = Plat_Rdtsc();
-}
-
-inline CCycleCount& CCycleCount::operator+=( CCycleCount const &other )
-{
- m_Int64 += other.m_Int64;
- return *this;
-}
-
-
-inline void CCycleCount::Add( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest )
-{
- dest.m_Int64 = rSrc1.m_Int64 + rSrc2.m_Int64;
-}
-
-inline void CCycleCount::Sub( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest )
-{
- dest.m_Int64 = rSrc1.m_Int64 - rSrc2.m_Int64;
-}
-
-inline uint64 CCycleCount::GetTimestamp()
-{
- CCycleCount c;
- c.Sample();
- return c.GetLongCycles();
-}
-
-inline bool CCycleCount::IsLessThan(CCycleCount const &other) const
-{
- return m_Int64 < other.m_Int64;
-}
-
-
-inline unsigned long CCycleCount::GetCycles() const
-{
- return (unsigned long)m_Int64;
-}
-
-inline uint64 CCycleCount::GetLongCycles() const
-{
- return m_Int64;
-}
-
-inline unsigned long CCycleCount::GetMicroseconds() const
-{
- return (unsigned long)((m_Int64 * 1000000) / g_ClockSpeed);
-}
-
-inline uint64 CCycleCount::GetUlMicroseconds() const
-{
- return ((m_Int64 * 1000000) / g_ClockSpeed);
-}
-
-
-inline double CCycleCount::GetMicrosecondsF() const
-{
- return (double)( m_Int64 * g_ClockSpeedMicrosecondsMultiplier );
-}
-
-
-inline void CCycleCount::SetMicroseconds( unsigned long nMicroseconds )
-{
- m_Int64 = ((uint64)nMicroseconds * g_ClockSpeed) / 1000000;
-}
-
-
-inline unsigned long CCycleCount::GetMilliseconds() const
-{
- return (unsigned long)((m_Int64 * 1000) / g_ClockSpeed);
-}
-
-
-inline double CCycleCount::GetMillisecondsF() const
-{
- return (double)( m_Int64 * g_ClockSpeedMillisecondsMultiplier );
-}
-
-
-inline double CCycleCount::GetSeconds() const
-{
- return (double)( m_Int64 * g_ClockSpeedSecondsMultiplier );
-}
-
-
-// -------------------------------------------------------------------------- //
-// CFastTimer inlines.
-// -------------------------------------------------------------------------- //
-inline void CFastTimer::Start()
-{
- m_Duration.Sample();
-#ifdef DEBUG_FASTTIMER
- m_bRunning = true;
-#endif
-}
-
-
-inline void CFastTimer::End()
-{
- CCycleCount cnt;
- cnt.Sample();
- if ( IsX360() )
- {
- // have to handle rollover, hires timer is only accurate to 32 bits
- // more than one overflow should not have occurred, otherwise caller should use a slower timer
- if ( (uint64)cnt.m_Int64 <= (uint64)m_Duration.m_Int64 )
- {
- // rollover occurred
- cnt.m_Int64 += 0x100000000LL;
- }
- }
-
- m_Duration.m_Int64 = cnt.m_Int64 - m_Duration.m_Int64;
-
-#ifdef DEBUG_FASTTIMER
- m_bRunning = false;
-#endif
-}
-
-inline CCycleCount CFastTimer::GetDurationInProgress() const
-{
- CCycleCount cnt;
- cnt.Sample();
- if ( IsX360() )
- {
- // have to handle rollover, hires timer is only accurate to 32 bits
- // more than one overflow should not have occurred, otherwise caller should use a slower timer
- if ( (uint64)cnt.m_Int64 <= (uint64)m_Duration.m_Int64 )
- {
- // rollover occurred
- cnt.m_Int64 += 0x100000000LL;
- }
- }
-
- CCycleCount result;
- result.m_Int64 = cnt.m_Int64 - m_Duration.m_Int64;
-
- return result;
-}
-
-
-inline int64 CFastTimer::GetClockSpeed()
-{
- return g_ClockSpeed;
-}
-
-
-inline CCycleCount const& CFastTimer::GetDuration() const
-{
-#ifdef DEBUG_FASTTIMER
- assert( !m_bRunning );
-#endif
- return m_Duration;
-}
-
-
-// -------------------------------------------------------------------------- //
-// CAverageCycleCounter inlines
-
-inline CAverageCycleCounter::CAverageCycleCounter()
- : m_nIters( 0 )
-{
-}
-
-inline void CAverageCycleCounter::Init()
-{
- m_Total.Init();
- m_Peak.Init();
- m_nIters = 0;
-}
-
-inline void CAverageCycleCounter::MarkIter( const CCycleCount &duration )
-{
- ++m_nIters;
- m_Total += duration;
- if ( m_Peak.IsLessThan( duration ) )
- m_Peak = duration;
-}
-
-inline unsigned CAverageCycleCounter::GetIters() const
-{
- return m_nIters;
-}
-
-inline double CAverageCycleCounter::GetAverageMilliseconds() const
-{
- if ( m_nIters )
- return (m_Total.GetMillisecondsF() / (double)m_nIters);
- else
- return 0;
-}
-
-inline double CAverageCycleCounter::GetTotalMilliseconds() const
-{
- return m_Total.GetMillisecondsF();
-}
-
-inline double CAverageCycleCounter::GetPeakMilliseconds() const
-{
- return m_Peak.GetMillisecondsF();
-}
-
-// -------------------------------------------------------------------------- //
-
-inline CAverageTimeMarker::CAverageTimeMarker( CAverageCycleCounter *pCounter )
-{
- m_pCounter = pCounter;
- m_Timer.Start();
-}
-
-inline CAverageTimeMarker::~CAverageTimeMarker()
-{
- m_Timer.End();
- m_pCounter->MarkIter( m_Timer.GetDuration() );
-}
-
-
-// CLimitTimer
-// Use this to time whether a desired interval of time has passed. It's extremely fast
-// to check while running. NOTE: CMicroSecOverage() and CMicroSecLeft() are not as fast to check.
-class CLimitTimer
-{
-public:
- CLimitTimer() {}
- CLimitTimer( uint64 cMicroSecDuration ) { SetLimit( cMicroSecDuration ); }
- void SetLimit( uint64 m_cMicroSecDuration );
- bool BLimitReached();
-
- int CMicroSecOverage();
- uint64 CMicroSecLeft();
-
-private:
- uint64 m_lCycleLimit;
-};
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Initializes the limit timer with a period of time to measure.
-// Input : cMicroSecDuration - How long a time period to measure
-//-----------------------------------------------------------------------------
-inline void CLimitTimer::SetLimit( uint64 cMicroSecDuration )
-{
- uint64 dlCycles = ( ( uint64 ) cMicroSecDuration * g_ClockSpeed ) / ( uint64 ) 1000000L;
- CCycleCount cycleCount;
- cycleCount.Sample( );
- m_lCycleLimit = cycleCount.GetLongCycles( ) + dlCycles;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Determines whether our specified time period has passed
-// Output: true if at least the specified time period has passed
-//-----------------------------------------------------------------------------
-inline bool CLimitTimer::BLimitReached( )
-{
- CCycleCount cycleCount;
- cycleCount.Sample( );
- return ( cycleCount.GetLongCycles( ) >= m_lCycleLimit );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: If we're over our specified time period, return the amount of the overage.
-// Output: # of microseconds since we reached our specified time period.
-//-----------------------------------------------------------------------------
-inline int CLimitTimer::CMicroSecOverage()
-{
- CCycleCount cycleCount;
- cycleCount.Sample();
- uint64 lcCycles = cycleCount.GetLongCycles();
-
- if ( lcCycles < m_lCycleLimit )
- return 0;
-
- return( ( int ) ( ( lcCycles - m_lCycleLimit ) * ( uint64 ) 1000000L / g_ClockSpeed ) );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: If we're under our specified time period, return the amount under.
-// Output: # of microseconds until we reached our specified time period, 0 if we've passed it
-//-----------------------------------------------------------------------------
-inline uint64 CLimitTimer::CMicroSecLeft()
-{
- CCycleCount cycleCount;
- cycleCount.Sample();
- uint64 lcCycles = cycleCount.GetLongCycles();
-
- if ( lcCycles >= m_lCycleLimit )
- return 0;
-
- return( ( uint64 ) ( ( m_lCycleLimit - lcCycles ) * ( uint64 ) 1000000L / g_ClockSpeed ) );
-}
-
-
-#endif // FASTTIMER_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef FASTTIMER_H
+#define FASTTIMER_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#ifdef _WIN32
+#include <intrin.h>
+#endif
+
+#include <assert.h>
+#include "tier0/platform.h"
+
+PLATFORM_INTERFACE uint64 g_ClockSpeed;
+#if defined( _X360 ) && defined( _CERT )
+PLATFORM_INTERFACE unsigned long g_dwFakeFastCounter;
+#endif
+
+PLATFORM_INTERFACE double g_ClockSpeedMicrosecondsMultiplier;
+PLATFORM_INTERFACE double g_ClockSpeedMillisecondsMultiplier;
+PLATFORM_INTERFACE double g_ClockSpeedSecondsMultiplier;
+
+class CCycleCount
+{
+friend class CFastTimer;
+
+public:
+ CCycleCount();
+ CCycleCount( uint64 cycles );
+
+ void Sample(); // Sample the clock. This takes about 34 clocks to execute (or 26,000 calls per millisecond on a P900).
+
+ void Init(); // Set to zero.
+ void Init( float initTimeMsec );
+ void Init( double initTimeMsec ) { Init( (float)initTimeMsec ); }
+ void Init( uint64 cycles );
+ bool IsLessThan( CCycleCount const &other ) const; // Compare two counts.
+
+ // Convert to other time representations. These functions are slow, so it's preferable to call them
+ // during display rather than inside a timing block.
+ unsigned long GetCycles() const;
+ uint64 GetLongCycles() const;
+
+ unsigned long GetMicroseconds() const;
+ uint64 GetUlMicroseconds() const;
+ double GetMicrosecondsF() const;
+ void SetMicroseconds( unsigned long nMicroseconds );
+
+ unsigned long GetMilliseconds() const;
+ double GetMillisecondsF() const;
+
+ double GetSeconds() const;
+
+ CCycleCount& operator+=( CCycleCount const &other );
+
+ // dest = rSrc1 + rSrc2
+ static void Add( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest ); // Add two samples together.
+
+ // dest = rSrc1 - rSrc2
+ static void Sub( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest ); // Add two samples together.
+
+ static uint64 GetTimestamp();
+
+ uint64 m_Int64;
+};
+
+class PLATFORM_CLASS CClockSpeedInit
+{
+public:
+ CClockSpeedInit()
+ {
+ Init();
+ }
+
+ static void Init();
+};
+
+class CFastTimer
+{
+public:
+ // These functions are fast to call and should be called from your sampling code.
+ void Start();
+ void End();
+
+ const CCycleCount & GetDuration() const; // Get the elapsed time between Start and End calls.
+ CCycleCount GetDurationInProgress() const; // Call without ending. Not that cheap.
+
+ // Return number of cycles per second on this processor.
+ static inline int64 GetClockSpeed();
+
+private:
+ CCycleCount m_Duration;
+#ifdef DEBUG_FASTTIMER
+ bool m_bRunning; // Are we currently running?
+#endif
+};
+
+
+// This is a helper class that times whatever block of code it's in
+class CTimeScope
+{
+public:
+ CTimeScope( CFastTimer *pTimer );
+ ~CTimeScope();
+
+private:
+ CFastTimer *m_pTimer;
+};
+
+inline CTimeScope::CTimeScope( CFastTimer *pTotal )
+{
+ m_pTimer = pTotal;
+ m_pTimer->Start();
+}
+
+inline CTimeScope::~CTimeScope()
+{
+ m_pTimer->End();
+}
+
+// This is a helper class that times whatever block of code it's in and
+// adds the total (int microseconds) to a global counter.
+class CTimeAdder
+{
+public:
+ CTimeAdder( CCycleCount *pTotal );
+ ~CTimeAdder();
+
+ void End();
+
+private:
+ CCycleCount *m_pTotal;
+ CFastTimer m_Timer;
+};
+
+inline CTimeAdder::CTimeAdder( CCycleCount *pTotal )
+{
+ m_pTotal = pTotal;
+ m_Timer.Start();
+}
+
+inline CTimeAdder::~CTimeAdder()
+{
+ End();
+}
+
+inline void CTimeAdder::End()
+{
+ if( m_pTotal )
+ {
+ m_Timer.End();
+ *m_pTotal += m_Timer.GetDuration();
+ m_pTotal = 0;
+ }
+}
+
+
+
+// -------------------------------------------------------------------------- //
+// Simple tool to support timing a block of code, and reporting the results on
+// program exit or at each iteration
+//
+// Macros used because dbg.h uses this header, thus Msg() is unavailable
+// -------------------------------------------------------------------------- //
+
+#define PROFILE_SCOPE(name) \
+ class C##name##ACC : public CAverageCycleCounter \
+ { \
+ public: \
+ ~C##name##ACC() \
+ { \
+ Msg("%-48s: %6.3f avg (%8.1f total, %7.3f peak, %5d iters)\n", \
+ #name, \
+ GetAverageMilliseconds(), \
+ GetTotalMilliseconds(), \
+ GetPeakMilliseconds(), \
+ GetIters() ); \
+ } \
+ }; \
+ static C##name##ACC name##_ACC; \
+ CAverageTimeMarker name##_ATM( &name##_ACC )
+
+#define TIME_SCOPE(name) \
+ class CTimeScopeMsg_##name \
+ { \
+ public: \
+ CTimeScopeMsg_##name() { m_Timer.Start(); } \
+ ~CTimeScopeMsg_##name() \
+ { \
+ m_Timer.End(); \
+ Msg( #name "time: %.4fms\n", m_Timer.GetDuration().GetMillisecondsF() ); \
+ } \
+ private: \
+ CFastTimer m_Timer; \
+ } name##_TSM;
+
+
+// -------------------------------------------------------------------------- //
+
+class CAverageCycleCounter
+{
+public:
+ CAverageCycleCounter();
+
+ void Init();
+ void MarkIter( const CCycleCount &duration );
+
+ unsigned GetIters() const;
+
+ double GetAverageMilliseconds() const;
+ double GetTotalMilliseconds() const;
+ double GetPeakMilliseconds() const;
+
+private:
+ unsigned m_nIters;
+ CCycleCount m_Total;
+ CCycleCount m_Peak;
+ bool m_fReport;
+ const tchar *m_pszName;
+};
+
+// -------------------------------------------------------------------------- //
+
+class CAverageTimeMarker
+{
+public:
+ CAverageTimeMarker( CAverageCycleCounter *pCounter );
+ ~CAverageTimeMarker();
+
+private:
+ CAverageCycleCounter *m_pCounter;
+ CFastTimer m_Timer;
+};
+
+
+// -------------------------------------------------------------------------- //
+// CCycleCount inlines.
+// -------------------------------------------------------------------------- //
+
+inline CCycleCount::CCycleCount()
+{
+ Init( (uint64)0 );
+}
+
+inline CCycleCount::CCycleCount( uint64 cycles )
+{
+ Init( cycles );
+}
+
+inline void CCycleCount::Init()
+{
+ Init( (uint64)0 );
+}
+
+inline void CCycleCount::Init( float initTimeMsec )
+{
+ if ( g_ClockSpeedMillisecondsMultiplier > 0 )
+ Init( (uint64)(initTimeMsec / g_ClockSpeedMillisecondsMultiplier) );
+ else
+ Init( (uint64)0 );
+}
+
+inline void CCycleCount::Init( uint64 cycles )
+{
+ m_Int64 = cycles;
+}
+
+inline void CCycleCount::Sample()
+{
+ m_Int64 = Plat_Rdtsc();
+}
+
+inline CCycleCount& CCycleCount::operator+=( CCycleCount const &other )
+{
+ m_Int64 += other.m_Int64;
+ return *this;
+}
+
+
+inline void CCycleCount::Add( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest )
+{
+ dest.m_Int64 = rSrc1.m_Int64 + rSrc2.m_Int64;
+}
+
+inline void CCycleCount::Sub( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest )
+{
+ dest.m_Int64 = rSrc1.m_Int64 - rSrc2.m_Int64;
+}
+
+inline uint64 CCycleCount::GetTimestamp()
+{
+ CCycleCount c;
+ c.Sample();
+ return c.GetLongCycles();
+}
+
+inline bool CCycleCount::IsLessThan(CCycleCount const &other) const
+{
+ return m_Int64 < other.m_Int64;
+}
+
+
+inline unsigned long CCycleCount::GetCycles() const
+{
+ return (unsigned long)m_Int64;
+}
+
+inline uint64 CCycleCount::GetLongCycles() const
+{
+ return m_Int64;
+}
+
+inline unsigned long CCycleCount::GetMicroseconds() const
+{
+ return (unsigned long)((m_Int64 * 1000000) / g_ClockSpeed);
+}
+
+inline uint64 CCycleCount::GetUlMicroseconds() const
+{
+ return ((m_Int64 * 1000000) / g_ClockSpeed);
+}
+
+
+inline double CCycleCount::GetMicrosecondsF() const
+{
+ return (double)( m_Int64 * g_ClockSpeedMicrosecondsMultiplier );
+}
+
+
+inline void CCycleCount::SetMicroseconds( unsigned long nMicroseconds )
+{
+ m_Int64 = ((uint64)nMicroseconds * g_ClockSpeed) / 1000000;
+}
+
+
+inline unsigned long CCycleCount::GetMilliseconds() const
+{
+ return (unsigned long)((m_Int64 * 1000) / g_ClockSpeed);
+}
+
+
+inline double CCycleCount::GetMillisecondsF() const
+{
+ return (double)( m_Int64 * g_ClockSpeedMillisecondsMultiplier );
+}
+
+
+inline double CCycleCount::GetSeconds() const
+{
+ return (double)( m_Int64 * g_ClockSpeedSecondsMultiplier );
+}
+
+
+// -------------------------------------------------------------------------- //
+// CFastTimer inlines.
+// -------------------------------------------------------------------------- //
+inline void CFastTimer::Start()
+{
+ m_Duration.Sample();
+#ifdef DEBUG_FASTTIMER
+ m_bRunning = true;
+#endif
+}
+
+
+inline void CFastTimer::End()
+{
+ CCycleCount cnt;
+ cnt.Sample();
+ if ( IsX360() )
+ {
+ // have to handle rollover, hires timer is only accurate to 32 bits
+ // more than one overflow should not have occurred, otherwise caller should use a slower timer
+ if ( (uint64)cnt.m_Int64 <= (uint64)m_Duration.m_Int64 )
+ {
+ // rollover occurred
+ cnt.m_Int64 += 0x100000000LL;
+ }
+ }
+
+ m_Duration.m_Int64 = cnt.m_Int64 - m_Duration.m_Int64;
+
+#ifdef DEBUG_FASTTIMER
+ m_bRunning = false;
+#endif
+}
+
+inline CCycleCount CFastTimer::GetDurationInProgress() const
+{
+ CCycleCount cnt;
+ cnt.Sample();
+ if ( IsX360() )
+ {
+ // have to handle rollover, hires timer is only accurate to 32 bits
+ // more than one overflow should not have occurred, otherwise caller should use a slower timer
+ if ( (uint64)cnt.m_Int64 <= (uint64)m_Duration.m_Int64 )
+ {
+ // rollover occurred
+ cnt.m_Int64 += 0x100000000LL;
+ }
+ }
+
+ CCycleCount result;
+ result.m_Int64 = cnt.m_Int64 - m_Duration.m_Int64;
+
+ return result;
+}
+
+
+inline int64 CFastTimer::GetClockSpeed()
+{
+ return g_ClockSpeed;
+}
+
+
+inline CCycleCount const& CFastTimer::GetDuration() const
+{
+#ifdef DEBUG_FASTTIMER
+ assert( !m_bRunning );
+#endif
+ return m_Duration;
+}
+
+
+// -------------------------------------------------------------------------- //
+// CAverageCycleCounter inlines
+
+inline CAverageCycleCounter::CAverageCycleCounter()
+ : m_nIters( 0 )
+{
+}
+
+inline void CAverageCycleCounter::Init()
+{
+ m_Total.Init();
+ m_Peak.Init();
+ m_nIters = 0;
+}
+
+inline void CAverageCycleCounter::MarkIter( const CCycleCount &duration )
+{
+ ++m_nIters;
+ m_Total += duration;
+ if ( m_Peak.IsLessThan( duration ) )
+ m_Peak = duration;
+}
+
+inline unsigned CAverageCycleCounter::GetIters() const
+{
+ return m_nIters;
+}
+
+inline double CAverageCycleCounter::GetAverageMilliseconds() const
+{
+ if ( m_nIters )
+ return (m_Total.GetMillisecondsF() / (double)m_nIters);
+ else
+ return 0;
+}
+
+inline double CAverageCycleCounter::GetTotalMilliseconds() const
+{
+ return m_Total.GetMillisecondsF();
+}
+
+inline double CAverageCycleCounter::GetPeakMilliseconds() const
+{
+ return m_Peak.GetMillisecondsF();
+}
+
+// -------------------------------------------------------------------------- //
+
+inline CAverageTimeMarker::CAverageTimeMarker( CAverageCycleCounter *pCounter )
+{
+ m_pCounter = pCounter;
+ m_Timer.Start();
+}
+
+inline CAverageTimeMarker::~CAverageTimeMarker()
+{
+ m_Timer.End();
+ m_pCounter->MarkIter( m_Timer.GetDuration() );
+}
+
+
+// CLimitTimer
+// Use this to time whether a desired interval of time has passed. It's extremely fast
+// to check while running. NOTE: CMicroSecOverage() and CMicroSecLeft() are not as fast to check.
+class CLimitTimer
+{
+public:
+ CLimitTimer() {}
+ CLimitTimer( uint64 cMicroSecDuration ) { SetLimit( cMicroSecDuration ); }
+ void SetLimit( uint64 m_cMicroSecDuration );
+ bool BLimitReached();
+
+ int CMicroSecOverage();
+ uint64 CMicroSecLeft();
+
+private:
+ uint64 m_lCycleLimit;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Initializes the limit timer with a period of time to measure.
+// Input : cMicroSecDuration - How long a time period to measure
+//-----------------------------------------------------------------------------
+inline void CLimitTimer::SetLimit( uint64 cMicroSecDuration )
+{
+ uint64 dlCycles = ( ( uint64 ) cMicroSecDuration * g_ClockSpeed ) / ( uint64 ) 1000000L;
+ CCycleCount cycleCount;
+ cycleCount.Sample( );
+ m_lCycleLimit = cycleCount.GetLongCycles( ) + dlCycles;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Determines whether our specified time period has passed
+// Output: true if at least the specified time period has passed
+//-----------------------------------------------------------------------------
+inline bool CLimitTimer::BLimitReached( )
+{
+ CCycleCount cycleCount;
+ cycleCount.Sample( );
+ return ( cycleCount.GetLongCycles( ) >= m_lCycleLimit );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: If we're over our specified time period, return the amount of the overage.
+// Output: # of microseconds since we reached our specified time period.
+//-----------------------------------------------------------------------------
+inline int CLimitTimer::CMicroSecOverage()
+{
+ CCycleCount cycleCount;
+ cycleCount.Sample();
+ uint64 lcCycles = cycleCount.GetLongCycles();
+
+ if ( lcCycles < m_lCycleLimit )
+ return 0;
+
+ return( ( int ) ( ( lcCycles - m_lCycleLimit ) * ( uint64 ) 1000000L / g_ClockSpeed ) );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: If we're under our specified time period, return the amount under.
+// Output: # of microseconds until we reached our specified time period, 0 if we've passed it
+//-----------------------------------------------------------------------------
+inline uint64 CLimitTimer::CMicroSecLeft()
+{
+ CCycleCount cycleCount;
+ cycleCount.Sample();
+ uint64 lcCycles = cycleCount.GetLongCycles();
+
+ if ( lcCycles >= m_lCycleLimit )
+ return 0;
+
+ return( ( uint64 ) ( ( m_lCycleLimit - lcCycles ) * ( uint64 ) 1000000L / g_ClockSpeed ) );
+}
+
+
+#endif // FASTTIMER_H