From eb228dcf3af8db371fd452e595396d8694c869fe Mon Sep 17 00:00:00 2001 From: richard Date: Fri, 8 Jan 2010 16:41:39 -0800 Subject: fast timer performance tuning --- indra/llcommon/llfasttimer.h | 205 ++++++++++++++++++++++--------------------- 1 file changed, 105 insertions(+), 100 deletions(-) (limited to 'indra/llcommon/llfasttimer.h') diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index f5c90291b8..ff96bd7abc 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -39,40 +39,24 @@ #define TIME_FAST_TIMERS 0 #if LL_WINDOWS +#include +#define LL_INLINE __forceinline // shift off lower 8 bits for lower resolution but longer term timing // on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing inline U32 get_cpu_clock_count_32() { - U32 ret_val; - __asm - { - _emit 0x0f - _emit 0x31 - shr eax,8 - shl edx,24 - or eax, edx - mov dword ptr [ret_val], eax - } - return ret_val; + U64 time_stamp = __rdtsc(); + return (U32)(time_stamp >> 8); } // return full timer value, *not* shifted by 8 bits inline U64 get_cpu_clock_count_64() { - U64 ret_val; - __asm - { - _emit 0x0f - _emit 0x31 - mov eax,eax - mov edx,edx - mov dword ptr [ret_val+4], edx - mov dword ptr [ret_val], eax - } - return ret_val; + return __rdtsc(); } - +#else +#define LL_INLINE #endif // LL_WINDOWS #if (LL_LINUX || LL_SOLARIS || LL_DARWIN) && (defined(__i386__) || defined(__amd64__)) @@ -114,9 +98,25 @@ class LLMutex; #include "llsd.h" -class LL_COMMON_API LLFastTimer +class LL_COMMON_API LLFastTimerUtil { public: + + class NamedTimer; + + struct LL_COMMON_API FrameState + { + FrameState(NamedTimer* timerp); + + U32 mSelfTimeCounter; + U32 mCalls; + FrameState* mParent; // info for caller timer + FrameState* mLastCaller; // used to bootstrap tree construction + NamedTimer* mTimer; + U16 mActiveCount; // number of timers with this ID active on stack + bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame + }; + // stores a "named" timer instance to be reused via multiple LLFastTimer stack instances class LL_COMMON_API NamedTimer : public LLInstanceTracker @@ -149,26 +149,13 @@ public: static NamedTimer& getRootNamedTimer(); - struct FrameState - { - FrameState(NamedTimer* timerp); - - U32 mSelfTimeCounter; - U32 mCalls; - FrameState* mParent; // info for caller timer - FrameState* mLastCaller; // used to bootstrap tree construction - NamedTimer* mTimer; - U16 mActiveCount; // number of timers with this ID active on stack - bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame - }; - S32 getFrameStateIndex() const { return mFrameStateIndex; } FrameState& getFrameState() const; private: - friend class LLFastTimer; + friend class LLFastTimerUtil; friend class NamedTimerFactory; // @@ -214,51 +201,101 @@ public: class LL_COMMON_API DeclareTimer : public LLInstanceTracker { + friend class LLFastTimer; public: DeclareTimer(const std::string& name, bool open); DeclareTimer(const std::string& name); static void updateCachedPointers(); - // convertable to NamedTimer::FrameState for convenient usage of LLFastTimer(declared_timer) - operator NamedTimer::FrameState&() { return *mFrameState; } private: - NamedTimer& mTimer; - NamedTimer::FrameState* mFrameState; + NamedTimer& mTimer; + FrameState* mFrameState; }; public: - static LLMutex* sLogLock; + static LLMutex* sLogLock; static std::queue sLogQueue; - static BOOL sLog; - static BOOL sMetricLog; + static BOOL sLog; + static BOOL sMetricLog; + static bool sPauseHistory; + static bool sResetHistory; + static U64 sTimerCycles; + static U32 sTimerCalls; - typedef std::vector info_list_t; + typedef std::vector info_list_t; static info_list_t& getFrameStateList(); - enum RootTimerMarker { ROOT }; - LLFastTimer(RootTimerMarker); + + // call this once a frame to reset timers + static void nextFrame(); - LLFastTimer(NamedTimer::FrameState& timer) - : mFrameState(&timer) + // dumps current cumulative frame stats to log + // call nextFrame() to reset timers + static void dumpCurTimes(); + + // call this to reset timer hierarchy, averages, etc. + static void reset(); + + static U64 countsPerSecond(); + static S32 getLastFrameIndex() { return sLastFrameIndex; } + static S32 getCurFrameIndex() { return sCurFrameIndex; } + + static void writeLog(std::ostream& os); + static const NamedTimer* getTimerByName(const std::string& name); + + struct CurTimerData + { + LLFastTimer* mCurTimer; + FrameState* mFrameState; + U32 mChildTime; + }; + static CurTimerData sCurTimerData; + +private: + static S32 sCurFrameIndex; + static S32 sLastFrameIndex; + static U64 sLastFrameTime; + static info_list_t* sTimerInfos; +}; + +class LLFastTimer +{ + friend LLFastTimerUtil::NamedTimer; +public: + LLFastTimer(LLFastTimerUtil::FrameState* state) + : mFrameState(state) + { + U32 start_time = get_cpu_clock_count_32(); + mStartTime = start_time; + mFrameState->mActiveCount++; + LLFastTimerUtil::sCurTimerData.mCurTimer = this; + LLFastTimerUtil::sCurTimerData.mFrameState = mFrameState; + LLFastTimerUtil::sCurTimerData.mChildTime = 0; + mLastTimerData = LLFastTimerUtil::sCurTimerData; + } + + LL_INLINE LLFastTimer(LLFastTimerUtil::DeclareTimer& timer) + : mFrameState(timer.mFrameState) { #if TIME_FAST_TIMERS U64 timer_start = get_cpu_clock_count_64(); #endif #if FAST_TIMER_ON - NamedTimer::FrameState* frame_state = &timer; - U32 cur_time = get_cpu_clock_count_32(); - mStartSelfTime = cur_time; - mStartTotalTime = cur_time; + LLFastTimerUtil::FrameState* frame_state = mFrameState; + mStartTime = get_cpu_clock_count_32(); frame_state->mActiveCount++; frame_state->mCalls++; // keep current parent as long as it is active when we are frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0); - mLastTimer = sCurTimer; - sCurTimer = this; + LLFastTimerUtil::CurTimerData* cur_timer_data = &LLFastTimerUtil::sCurTimerData; + mLastTimerData = *cur_timer_data; + cur_timer_data->mCurTimer = this; + cur_timer_data->mFrameState = frame_state; + cur_timer_data->mChildTime = 0; #endif #if TIME_FAST_TIMERS U64 timer_end = get_cpu_clock_count_64(); @@ -266,26 +303,26 @@ public: #endif } - ~LLFastTimer() + LL_INLINE ~LLFastTimer() { #if TIME_FAST_TIMERS U64 timer_start = get_cpu_clock_count_64(); #endif #if FAST_TIMER_ON - NamedTimer::FrameState* frame_state = mFrameState; - U32 cur_time = get_cpu_clock_count_32(); - frame_state->mSelfTimeCounter += cur_time - mStartSelfTime; + LLFastTimerUtil::FrameState* frame_state = mFrameState; + U32 total_time = get_cpu_clock_count_32() - mStartTime; + frame_state->mSelfTimeCounter += total_time - LLFastTimerUtil::sCurTimerData.mChildTime; frame_state->mActiveCount--; - LLFastTimer* last_timer = mLastTimer; - sCurTimer = last_timer; // store last caller to bootstrap tree creation - frame_state->mLastCaller = last_timer->mFrameState; + // do this in the destructor in case of recursion to get topmost caller + frame_state->mLastCaller = mLastTimerData.mFrameState; // we are only tracking self time, so subtract our total time delta from parents - U32 total_time = cur_time - mStartTotalTime; - last_timer->mStartSelfTime += total_time; + mLastTimerData.mChildTime += total_time; + + LLFastTimerUtil::sCurTimerData = mLastTimerData; #endif #if TIME_FAST_TIMERS U64 timer_end = get_cpu_clock_count_64(); @@ -293,42 +330,10 @@ public: sTimerCalls++; #endif } - - - // call this once a frame to reset timers - static void nextFrame(); - - // dumps current cumulative frame stats to log - // call nextFrame() to reset timers - static void dumpCurTimes(); - - // call this to reset timer hierarchy, averages, etc. - static void reset(); - - static U64 countsPerSecond(); - static S32 getLastFrameIndex() { return sLastFrameIndex; } - static S32 getCurFrameIndex() { return sCurFrameIndex; } - - static void writeLog(std::ostream& os); - static const NamedTimer* getTimerByName(const std::string& name); - -public: - static bool sPauseHistory; - static bool sResetHistory; - static U64 sTimerCycles; - static U32 sTimerCalls; - private: - static LLFastTimer* sCurTimer; - static S32 sCurFrameIndex; - static S32 sLastFrameIndex; - static U64 sLastFrameTime; - static info_list_t* sTimerInfos; - - U32 mStartSelfTime; // start time + time of all child timers - U32 mStartTotalTime; // start time + time of all child timers - NamedTimer::FrameState* mFrameState; - LLFastTimer* mLastTimer; + U32 mStartTime; + LLFastTimerUtil::FrameState* mFrameState; + LLFastTimerUtil::CurTimerData mLastTimerData; }; #endif // LL_LLFASTTIMER_H -- cgit v1.2.3 From daa4965fe053dbd1af1f9665b29a4a10ac31cfea Mon Sep 17 00:00:00 2001 From: richard Date: Mon, 11 Jan 2010 12:05:13 -0800 Subject: renamed LLFastTimerUtil to LLFastTimer --- indra/llcommon/llfasttimer.h | 136 +++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 76 deletions(-) (limited to 'indra/llcommon/llfasttimer.h') diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index ff96bd7abc..645bbb88ff 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -97,8 +97,7 @@ class LLMutex; #include #include "llsd.h" - -class LL_COMMON_API LLFastTimerUtil +class LL_COMMON_API LLFastTimer { public: @@ -153,9 +152,8 @@ public: FrameState& getFrameState() const; - private: - friend class LLFastTimerUtil; + friend class LLFastTimer; friend class NamedTimerFactory; // @@ -172,7 +170,6 @@ public: static void buildHierarchy(); static void resetFrame(); static void reset(); - // // members @@ -194,7 +191,6 @@ public: std::vector mChildren; bool mCollapsed; // don't show children bool mNeedsSorting; // sort children whenever child added - }; // used to statically declare a new named timer @@ -213,77 +209,17 @@ public: FrameState* mFrameState; }; - -public: - static LLMutex* sLogLock; - static std::queue sLogQueue; - static BOOL sLog; - static BOOL sMetricLog; - static bool sPauseHistory; - static bool sResetHistory; - static U64 sTimerCycles; - static U32 sTimerCalls; - - typedef std::vector info_list_t; - static info_list_t& getFrameStateList(); - - - // call this once a frame to reset timers - static void nextFrame(); - - // dumps current cumulative frame stats to log - // call nextFrame() to reset timers - static void dumpCurTimes(); - - // call this to reset timer hierarchy, averages, etc. - static void reset(); - - static U64 countsPerSecond(); - static S32 getLastFrameIndex() { return sLastFrameIndex; } - static S32 getCurFrameIndex() { return sCurFrameIndex; } - - static void writeLog(std::ostream& os); - static const NamedTimer* getTimerByName(const std::string& name); - - struct CurTimerData - { - LLFastTimer* mCurTimer; - FrameState* mFrameState; - U32 mChildTime; - }; - static CurTimerData sCurTimerData; - -private: - static S32 sCurFrameIndex; - static S32 sLastFrameIndex; - static U64 sLastFrameTime; - static info_list_t* sTimerInfos; -}; - -class LLFastTimer -{ - friend LLFastTimerUtil::NamedTimer; public: - LLFastTimer(LLFastTimerUtil::FrameState* state) - : mFrameState(state) - { - U32 start_time = get_cpu_clock_count_32(); - mStartTime = start_time; - mFrameState->mActiveCount++; - LLFastTimerUtil::sCurTimerData.mCurTimer = this; - LLFastTimerUtil::sCurTimerData.mFrameState = mFrameState; - LLFastTimerUtil::sCurTimerData.mChildTime = 0; - mLastTimerData = LLFastTimerUtil::sCurTimerData; - } + LLFastTimer(LLFastTimer::FrameState* state); - LL_INLINE LLFastTimer(LLFastTimerUtil::DeclareTimer& timer) + LL_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer) : mFrameState(timer.mFrameState) { #if TIME_FAST_TIMERS U64 timer_start = get_cpu_clock_count_64(); #endif #if FAST_TIMER_ON - LLFastTimerUtil::FrameState* frame_state = mFrameState; + LLFastTimer::FrameState* frame_state = mFrameState; mStartTime = get_cpu_clock_count_32(); frame_state->mActiveCount++; @@ -291,7 +227,7 @@ public: // keep current parent as long as it is active when we are frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0); - LLFastTimerUtil::CurTimerData* cur_timer_data = &LLFastTimerUtil::sCurTimerData; + LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData; mLastTimerData = *cur_timer_data; cur_timer_data->mCurTimer = this; cur_timer_data->mFrameState = frame_state; @@ -309,10 +245,10 @@ public: U64 timer_start = get_cpu_clock_count_64(); #endif #if FAST_TIMER_ON - LLFastTimerUtil::FrameState* frame_state = mFrameState; + LLFastTimer::FrameState* frame_state = mFrameState; U32 total_time = get_cpu_clock_count_32() - mStartTime; - frame_state->mSelfTimeCounter += total_time - LLFastTimerUtil::sCurTimerData.mChildTime; + frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime; frame_state->mActiveCount--; // store last caller to bootstrap tree creation @@ -322,7 +258,7 @@ public: // we are only tracking self time, so subtract our total time delta from parents mLastTimerData.mChildTime += total_time; - LLFastTimerUtil::sCurTimerData = mLastTimerData; + LLFastTimer::sCurTimerData = mLastTimerData; #endif #if TIME_FAST_TIMERS U64 timer_end = get_cpu_clock_count_64(); @@ -330,10 +266,58 @@ public: sTimerCalls++; #endif } + +public: + static LLMutex* sLogLock; + static std::queue sLogQueue; + static BOOL sLog; + static BOOL sMetricLog; + static bool sPauseHistory; + static bool sResetHistory; + static U64 sTimerCycles; + static U32 sTimerCalls; + + typedef std::vector info_list_t; + static info_list_t& getFrameStateList(); + + + // call this once a frame to reset timers + static void nextFrame(); + + // dumps current cumulative frame stats to log + // call nextFrame() to reset timers + static void dumpCurTimes(); + + // call this to reset timer hierarchy, averages, etc. + static void reset(); + + static U64 countsPerSecond(); + static S32 getLastFrameIndex() { return sLastFrameIndex; } + static S32 getCurFrameIndex() { return sCurFrameIndex; } + + static void writeLog(std::ostream& os); + static const NamedTimer* getTimerByName(const std::string& name); + + struct CurTimerData + { + LLFastTimer* mCurTimer; + FrameState* mFrameState; + U32 mChildTime; + }; + static CurTimerData sCurTimerData; + private: - U32 mStartTime; - LLFastTimerUtil::FrameState* mFrameState; - LLFastTimerUtil::CurTimerData mLastTimerData; + static S32 sCurFrameIndex; + static S32 sLastFrameIndex; + static U64 sLastFrameTime; + static info_list_t* sTimerInfos; + + U32 mStartTime; + LLFastTimer::FrameState* mFrameState; + LLFastTimer::CurTimerData mLastTimerData; + }; +typedef class LLFastTimer LLFastTimer; + #endif // LL_LLFASTTIMER_H -- cgit v1.2.3