diff options
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/llfasttimer.cpp | 45 | ||||
-rw-r--r-- | indra/llcommon/llfasttimer.h | 13 | ||||
-rw-r--r-- | indra/llcommon/lltrace.h | 24 | ||||
-rw-r--r-- | indra/llcommon/lltracerecording.cpp | 29 | ||||
-rw-r--r-- | indra/llcommon/lltracerecording.h | 11 | ||||
-rw-r--r-- | indra/llcommon/lltracethreadrecorder.cpp | 33 | ||||
-rw-r--r-- | indra/llcommon/lltracethreadrecorder.h | 12 |
7 files changed, 123 insertions, 44 deletions
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index a144a8c94e..0ea91d7e51 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -256,12 +256,16 @@ void TimeBlock::processTimes() while(cur_timer && cur_timer->mParentTimerData.mActiveTimer != cur_timer) { U64 cumulative_time_delta = cur_time - cur_timer->mStartTime; - - accumulator->mTotalTimeCounter += cumulative_time_delta; - accumulator->mChildTimeCounter += stack_record->mChildTime; + U64 child_time = stack_record->mChildTime + - (accumulator->mSelfTimeCounter - cur_timer->mStartSelfTimeCounter) + - (accumulator->mChildTimeCounter - cur_timer->mStartChildTimeCounter); + accumulator->mChildTimeCounter += child_time; + accumulator->mSelfTimeCounter += cumulative_time_delta - child_time; stack_record->mChildTime = 0; cur_timer->mStartTime = cur_time; + cur_timer->mStartSelfTimeCounter = accumulator->mSelfTimeCounter; + cur_timer->mStartChildTimeCounter = accumulator->mChildTimeCounter; stack_record = &cur_timer->mParentTimerData; accumulator = stack_record->mTimeBlock->getPrimaryAccumulator(); @@ -401,7 +405,9 @@ void TimeBlock::writeLog(std::ostream& os) TimeBlockAccumulator::TimeBlockAccumulator() : mChildTimeCounter(0), - mTotalTimeCounter(0), + mSelfTimeCounter(0), + mStartChildTimeCounter(0), + mStartSelfTimeCounter(0), mCalls(0), mLastCaller(NULL), mActiveCount(0), @@ -411,8 +417,8 @@ TimeBlockAccumulator::TimeBlockAccumulator() void TimeBlockAccumulator::addSamples( const TimeBlockAccumulator& other ) { - mChildTimeCounter += other.mChildTimeCounter; - mTotalTimeCounter += other.mTotalTimeCounter; + mChildTimeCounter += other.mChildTimeCounter - other.mStartChildTimeCounter; + mSelfTimeCounter += other.mSelfTimeCounter - other.mStartSelfTimeCounter; mCalls += other.mCalls; mLastCaller = other.mLastCaller; mActiveCount = other.mActiveCount; @@ -422,9 +428,32 @@ void TimeBlockAccumulator::addSamples( const TimeBlockAccumulator& other ) void TimeBlockAccumulator::reset( const TimeBlockAccumulator* other ) { - mTotalTimeCounter = 0; - mChildTimeCounter = 0; mCalls = 0; + if (other) + { + mStartSelfTimeCounter = other->mSelfTimeCounter; + mSelfTimeCounter = mStartSelfTimeCounter; + mStartChildTimeCounter = other->mChildTimeCounter; + mChildTimeCounter = mStartChildTimeCounter; + + mLastCaller = other->mLastCaller; + mActiveCount = other->mActiveCount; + mMoveUpTree = other->mMoveUpTree; + mParent = other->mParent; + } + else + { + mStartSelfTimeCounter = mSelfTimeCounter; + mStartChildTimeCounter = mChildTimeCounter; + } } +LLUnit<LLUnits::Seconds, F64> BlockTimer::getElapsedTime() +{ + U64 total_time = TimeBlock::getCPUClockCount64() - mStartTime; + + return (F64)total_time / (F64)TimeBlock::countsPerSecond(); +} + + } // namespace LLTrace diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 726db70fbe..28e54a37de 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -71,9 +71,13 @@ public: BlockTimer(TimeBlock& timer); ~BlockTimer(); + LLUnit<LLUnits::Seconds, F64> getElapsedTime(); + private: U64 mStartTime; + U64 mStartSelfTimeCounter; + U64 mStartChildTimeCounter; BlockTimerStackRecord mParentTimerData; }; @@ -279,6 +283,8 @@ LL_FORCE_INLINE BlockTimer::BlockTimer(TimeBlock& timer) BlockTimerStackRecord* cur_timer_data = ThreadTimerStack::getIfExists(); TimeBlockAccumulator* accumulator = timer.getPrimaryAccumulator(); accumulator->mActiveCount++; + mStartSelfTimeCounter = accumulator->mSelfTimeCounter; + mStartChildTimeCounter = accumulator->mChildTimeCounter; // keep current parent as long as it is active when we are accumulator->mMoveUpTree |= (accumulator->mParent->getPrimaryAccumulator()->mActiveCount == 0); @@ -298,9 +304,12 @@ LL_FORCE_INLINE BlockTimer::~BlockTimer() BlockTimerStackRecord* cur_timer_data = ThreadTimerStack::getIfExists(); TimeBlockAccumulator* accumulator = cur_timer_data->mTimeBlock->getPrimaryAccumulator(); + U64 child_time = cur_timer_data->mChildTime + - (accumulator->mSelfTimeCounter - mStartSelfTimeCounter) + - (accumulator->mChildTimeCounter - mStartChildTimeCounter); accumulator->mCalls++; - accumulator->mChildTimeCounter += cur_timer_data->mChildTime; - accumulator->mTotalTimeCounter += total_time; + accumulator->mChildTimeCounter += child_time; + accumulator->mSelfTimeCounter += total_time - cur_timer_data->mChildTime; accumulator->mActiveCount--; // store last caller to bootstrap tree creation diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 0f927bad53..8c3259eea9 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -243,8 +243,6 @@ namespace LLTrace : public LLInstanceTracker<TraceType<ACCUMULATOR>, std::string> { public: - typedef typename MeanValueType<TraceType<ACCUMULATOR> >::type mean_t; - TraceType(const char* name, const char* description = NULL) : LLInstanceTracker<TraceType<ACCUMULATOR>, std::string>(name), mName(name), @@ -446,8 +444,10 @@ namespace LLTrace // // members // - U64 mChildTimeCounter, - mTotalTimeCounter; + U64 mStartChildTimeCounter, + mStartSelfTimeCounter, + mChildTimeCounter, + mSelfTimeCounter; U32 mCalls; class TimeBlock* mParent; // last acknowledged parent of this time block class TimeBlock* mLastCaller; // used to bootstrap tree construction @@ -468,7 +468,6 @@ namespace LLTrace : public TraceType<TimeBlockAccumulator> { public: - typedef F32 mean_t; TraceType(const char* name, const char* description = "") : TraceType<TimeBlockAccumulator>(name, description) @@ -476,17 +475,30 @@ namespace LLTrace }; template<> + struct MeanValueType<TraceType<TimeBlockAccumulator::CallCountAspect> > + { + typedef F64 type; + }; + + + template<> class TraceType<TimeBlockAccumulator::SelfTimeAspect> : public TraceType<TimeBlockAccumulator> { public: - typedef F32 mean_t; TraceType(const char* name, const char* description = "") : TraceType<TimeBlockAccumulator>(name, description) {} }; + template<> + struct MeanValueType<TraceType<TimeBlockAccumulator::SelfTimeAspect> > + { + typedef LLUnit<LLUnits::Seconds, F64> type; + }; + + class TimeBlock; class TimeBlockTreeNode { diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index 913c4cbdad..2af9041863 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -109,9 +109,17 @@ void Recording::handleSplitTo(Recording& other) { stop(); other.restart(); + syncTo(other); +} + +void Recording::syncTo(Recording& other) +{ + other.mCountsFloat.write()->reset(mCountsFloat); other.mMeasurementsFloat.write()->reset(mMeasurementsFloat); + other.mCounts.write()->reset(mCounts); other.mMeasurements.write()->reset(mMeasurements); - //TODO: figure out how to get seamless handoff of timing stats + other.mStackTimers.write()->reset(mStackTimers); + other.mMemStats.write()->reset(mMemStats); } void Recording::makePrimary() @@ -174,12 +182,15 @@ void Recording::mergeRecording( const Recording& other) LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumulator>& stat) const { - return (F64)(*mStackTimers)[stat.getIndex()].mTotalTimeCounter / (F64)LLTrace::TimeBlock::countsPerSecond(); + const TimeBlockAccumulator& accumulator = (*mStackTimers)[stat.getIndex()]; + return (F64)(accumulator.mSelfTimeCounter - accumulator.mStartSelfTimeCounter + accumulator.mChildTimeCounter - accumulator.mStartChildTimeCounter) + / (F64)LLTrace::TimeBlock::countsPerSecond(); } LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumulator::SelfTimeAspect>& stat) const { - return ((F64)(*mStackTimers)[stat.getIndex()].mTotalTimeCounter - (F64)(*mStackTimers)[stat.getIndex()].mChildTimeCounter) / (F64)LLTrace::TimeBlock::countsPerSecond(); + const TimeBlockAccumulator& accumulator = (*mStackTimers)[stat.getIndex()]; + return (F64)(accumulator.mSelfTimeCounter - accumulator.mStartSelfTimeCounter) / (F64)LLTrace::TimeBlock::countsPerSecond(); } @@ -190,12 +201,18 @@ U32 Recording::getSum(const TraceType<TimeBlockAccumulator::CallCountAspect>& st LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccumulator>& stat) const { - return (F64)(*mStackTimers)[stat.getIndex()].mTotalTimeCounter / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds); + const TimeBlockAccumulator& accumulator = (*mStackTimers)[stat.getIndex()]; + + return (F64)(accumulator.mSelfTimeCounter - accumulator.mStartSelfTimeCounter + accumulator.mChildTimeCounter - accumulator.mStartChildTimeCounter) + / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds); } LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccumulator::SelfTimeAspect>& stat) const { - return ((F64)(*mStackTimers)[stat.getIndex()].mTotalTimeCounter - (F64)(*mStackTimers)[stat.getIndex()].mChildTimeCounter) / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds); + const TimeBlockAccumulator& accumulator = (*mStackTimers)[stat.getIndex()]; + + return (F64)(accumulator.mSelfTimeCounter - accumulator.mStartSelfTimeCounter) + / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds); } F32 Recording::getPerSec(const TraceType<TimeBlockAccumulator::CallCountAspect>& stat) const @@ -520,7 +537,7 @@ void ExtendableRecording::splitFrom(ExtendableRecording& other) PeriodicRecording& get_frame_recording() { - static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(64, PeriodicRecording::STARTED)); + static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(200, PeriodicRecording::STARTED)); return *sRecording; } diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index 05e1577a5a..16fee04979 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -119,6 +119,7 @@ namespace LLTrace // gather data from recording, ignoring time relationship (for example, pulling data from slave threads) void mergeRecording(const Recording& other); + // grab latest recorded data void update(); // Timer accessors @@ -217,6 +218,8 @@ namespace LLTrace LLUnit<LLUnits::Seconds, F64> getDuration() const { return LLUnit<LLUnits::Seconds, F64>(mElapsedSeconds); } + void syncTo(Recording& other); + private: friend class ThreadRecorder; @@ -337,9 +340,9 @@ namespace LLTrace } template <typename T> - typename TraceType<T>::mean_t getPeriodMean(const TraceType<T>& stat) const + typename MeanValueType<TraceType<T> >::type getPeriodMean(const TraceType<T>& stat) const { - typename TraceType<T>::mean_t mean = 0.0; + typename MeanValueType<TraceType<T> >::type mean = 0.0; for (S32 i = 0; i < mNumPeriods; i++) { if (mRecordingPeriods[i].getDuration() > 0.f) @@ -352,9 +355,9 @@ namespace LLTrace } template <typename T> - typename TraceType<T>::mean_t getPeriodMeanPerSec(const TraceType<T>& stat) const + typename MeanValueType<TraceType<T> >::type getPeriodMeanPerSec(const TraceType<T>& stat) const { - typename TraceType<T>::mean_t mean = 0.0; + typename MeanValueType<TraceType<T> >::type mean = 0.0; for (S32 i = 0; i < mNumPeriods; i++) { if (mRecordingPeriods[i].getDuration() > 0.f) diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 7b493a651e..113febcca8 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -76,7 +76,7 @@ ThreadRecorder::~ThreadRecorder() while(mActiveRecordings.size()) { - mActiveRecordings.front().mTargetRecording->stop(); + mActiveRecordings.front()->mTargetRecording->stop(); } set_thread_recorder(NULL); delete[] mTimeBlockTreeNodes; @@ -94,31 +94,37 @@ TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode(S32 index) void ThreadRecorder::activate( Recording* recording ) { - mActiveRecordings.push_front(ActiveRecording(recording)); - mActiveRecordings.front().mBaseline.makePrimary(); + ActiveRecording* active_recording = new ActiveRecording(recording); + if (!mActiveRecordings.empty()) + { + mActiveRecordings.front()->mBaseline.syncTo(active_recording->mBaseline); + } + mActiveRecordings.push_front(active_recording); + + mActiveRecordings.front()->mBaseline.makePrimary(); } -std::list<ThreadRecorder::ActiveRecording>::iterator ThreadRecorder::update( Recording* recording ) +ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::update( Recording* recording ) { - std::list<ActiveRecording>::iterator it, end_it; + active_recording_list_t::iterator it, end_it; for (it = mActiveRecordings.begin(), end_it = mActiveRecordings.end(); it != end_it; ++it) { - std::list<ActiveRecording>::iterator next_it = it; + active_recording_list_t::iterator next_it = it; ++next_it; // if we have another recording further down in the stack... if (next_it != mActiveRecordings.end()) { // ...push our gathered data down to it - next_it->mBaseline.appendRecording(it->mBaseline); + (*next_it)->mBaseline.appendRecording((*it)->mBaseline); } // copy accumulated measurements into result buffer and clear accumulator (mBaseline) - it->moveBaselineToTarget(); + (*it)->moveBaselineToTarget(); - if (it->mTargetRecording == recording) + if ((*it)->mTargetRecording == recording) { // found the recording, so return it break; @@ -142,17 +148,18 @@ AccumulatorBuffer<MemStatAccumulator> gMemStats; void ThreadRecorder::deactivate( Recording* recording ) { - std::list<ActiveRecording>::iterator it = update(recording); + active_recording_list_t::iterator it = update(recording); if (it != mActiveRecordings.end()) { // and if we've found the recording we wanted to update - std::list<ActiveRecording>::iterator next_it = it; + active_recording_list_t::iterator next_it = it; ++next_it; if (next_it != mActiveRecordings.end()) { - next_it->mTargetRecording->makePrimary(); + (*next_it)->mTargetRecording->makePrimary(); } + delete *it; mActiveRecordings.erase(it); } } @@ -244,7 +251,7 @@ void MasterThreadRecorder::pullFromSlaveThreads() LLMutexLock lock(&mSlaveListMutex); - Recording& target_recording = mActiveRecordings.front().mBaseline; + Recording& target_recording = mActiveRecordings.front()->mBaseline; for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); it != end_it; ++it) diff --git a/indra/llcommon/lltracethreadrecorder.h b/indra/llcommon/lltracethreadrecorder.h index 337035974c..0e6c091900 100644 --- a/indra/llcommon/lltracethreadrecorder.h +++ b/indra/llcommon/lltracethreadrecorder.h @@ -39,13 +39,14 @@ namespace LLTrace { protected: struct ActiveRecording; + typedef std::list<ActiveRecording*> active_recording_list_t; public: ThreadRecorder(); virtual ~ThreadRecorder(); void activate(Recording* recording); - std::list<struct ActiveRecording>::iterator update(Recording* recording); + active_recording_list_t::iterator update(Recording* recording); void deactivate(Recording* recording); virtual void pushToMaster() = 0; @@ -63,11 +64,12 @@ namespace LLTrace void moveBaselineToTarget(); }; Recording mThreadRecording; - std::list<ActiveRecording> mActiveRecordings; - class BlockTimer* mRootTimer; - TimeBlockTreeNode* mTimeBlockTreeNodes; - size_t mNumTimeBlockTreeNodes; + active_recording_list_t mActiveRecordings; + + class BlockTimer* mRootTimer; + TimeBlockTreeNode* mTimeBlockTreeNodes; + size_t mNumTimeBlockTreeNodes; }; class LL_COMMON_API MasterThreadRecorder : public ThreadRecorder |