SH-3275 WIP Update viewer metrics system to be more flexible

implemented minimal merging logic
made recordings ligher weight by moving live tracking data into threadrecorder
master
Richard Linden 2012-10-02 17:14:12 -07:00
parent dbe9742703
commit 7196619b4a
4 changed files with 77 additions and 48 deletions

View File

@ -66,18 +66,17 @@ MasterThreadRecorder& getMasterThreadRecorder()
///////////////////////////////////////////////////////////////////////
ThreadRecorder::ThreadRecorder()
: mPrimaryRecording(NULL)
{
get_thread_recorder() = this;
mPrimaryRecording.makePrimary();
mFullRecording.start();
}
ThreadRecorder::ThreadRecorder( const ThreadRecorder& other )
: mPrimaryRecording(other.mPrimaryRecording),
mFullRecording(other.mFullRecording)
: mFullRecording(other.mFullRecording),
mPrimaryRecording(NULL)
{
get_thread_recorder() = this;
mPrimaryRecording.makePrimary();
mFullRecording.start();
}
@ -89,39 +88,74 @@ ThreadRecorder::~ThreadRecorder()
//TODO: remove this and use llviewerstats recording
Recording* ThreadRecorder::getPrimaryRecording()
{
return &mPrimaryRecording;
return mPrimaryRecording;
}
void ThreadRecorder::activate( Recording* recorder )
void ThreadRecorder::activate( Recording* recording )
{
for (std::list<Recording*>::iterator it = mActiveRecordings.begin(), end_it = mActiveRecordings.end();
it != end_it;
++it)
{
(*it)->mMeasurements.write()->mergeSamples(*mPrimaryRecording.mMeasurements);
}
mPrimaryRecording.mMeasurements.write()->reset();
recorder->initDeltas(mPrimaryRecording);
mActiveRecordings.push_front(recorder);
mActiveRecordings.push_front(ActiveRecording(mPrimaryRecording, recording));
mActiveRecordings.front().mBaseline.makePrimary();
mPrimaryRecording = &mActiveRecordings.front().mBaseline;
}
//TODO: consider merging results down the list to one past the buffered item.
// this would require 2 buffers per sampler, to separate current total from running total
void ThreadRecorder::deactivate( Recording* recorder )
void ThreadRecorder::deactivate( Recording* recording )
{
recorder->mergeDeltas(mPrimaryRecording);
// TODO: replace with intrusive list
std::list<Recording*>::iterator found_it = std::find(mActiveRecordings.begin(), mActiveRecordings.end(), recorder);
if (found_it != mActiveRecordings.end())
for (std::list<ActiveRecording>::iterator it = mActiveRecordings.begin(), end_it = mActiveRecordings.end();
it != end_it;
++it)
{
mActiveRecordings.erase(found_it);
std::list<ActiveRecording>::iterator next_it = it;
if (++next_it != mActiveRecordings.end())
{
next_it->mergeMeasurements((*it));
}
it->flushAccumulators(mPrimaryRecording);
if (it->mTargetRecording == recording)
{
if (next_it != mActiveRecordings.end())
{
next_it->mBaseline.makePrimary();
mPrimaryRecording = &next_it->mBaseline;
}
mActiveRecordings.erase(it);
break;
}
}
}
ThreadRecorder::ActiveRecording::ActiveRecording( Recording* source, Recording* target )
: mTargetRecording(target)
{
// take snapshots of current values rates and timers
if (source)
{
mBaseline.mRates.write()->copyFrom(*source->mRates);
mBaseline.mStackTimers.write()->copyFrom(*source->mStackTimers);
}
}
void ThreadRecorder::ActiveRecording::mergeMeasurements(ThreadRecorder::ActiveRecording& other)
{
mBaseline.mMeasurements.write()->mergeSamples(*other.mBaseline.mMeasurements);
}
void ThreadRecorder::ActiveRecording::flushAccumulators(Recording* current)
{
// accumulate statistics-like measurements
mTargetRecording->mMeasurements.write()->mergeSamples(*mBaseline.mMeasurements);
// for rate-like measurements, merge total change since baseline
mTargetRecording->mRates.write()->mergeDeltas(*mBaseline.mRates, *current->mRates);
mTargetRecording->mStackTimers.write()->mergeDeltas(*mBaseline.mStackTimers, *current->mStackTimers);
// reset baselines
mBaseline.mRates.write()->copyFrom(*current->mRates);
mBaseline.mStackTimers.write()->copyFrom(*current->mStackTimers);
}
///////////////////////////////////////////////////////////////////////
// SlaveThreadRecorder
///////////////////////////////////////////////////////////////////////

View File

@ -497,9 +497,19 @@ namespace LLTrace
Recording* getPrimaryRecording();
protected:
Recording mPrimaryRecording;
struct ActiveRecording
{
ActiveRecording(Recording* source, Recording* target);
Recording* mTargetRecording;
Recording mBaseline;
void mergeMeasurements(ActiveRecording& other);
void flushAccumulators(Recording* current);
};
Recording* mPrimaryRecording;
Recording mFullRecording;
std::list<Recording*> mActiveRecordings;
std::list<ActiveRecording> mActiveRecordings;
};
class LL_COMMON_API MasterThreadRecorder : public ThreadRecorder

View File

@ -39,17 +39,13 @@ namespace LLTrace
Recording::Recording()
: mElapsedSeconds(0),
mIsStarted(false),
mRatesStart(new AccumulatorBuffer<RateAccumulator<F32> >()),
mRates(new AccumulatorBuffer<RateAccumulator<F32> >()),
mMeasurements(new AccumulatorBuffer<MeasurementAccumulator<F32> >()),
mStackTimers(new AccumulatorBuffer<TimerAccumulator>()),
mStackTimersStart(new AccumulatorBuffer<TimerAccumulator>())
{
}
mStackTimers(new AccumulatorBuffer<TimerAccumulator>())
{}
Recording::~Recording()
{
}
{}
void Recording::start()
{
@ -107,18 +103,10 @@ void Recording::mergeSamples( const Recording& other )
mStackTimers.write()->mergeSamples(*other.mStackTimers);
}
void Recording::initDeltas( const Recording& other )
void Recording::mergeDeltas(const Recording& baseline, const Recording& target)
{
mRatesStart.write()->copyFrom(*other.mRates);
mStackTimersStart.write()->copyFrom(*other.mStackTimers);
}
void Recording::mergeDeltas( const Recording& other )
{
mRates.write()->mergeDeltas(*mRatesStart, *other.mRates);
mStackTimers.write()->mergeDeltas(*mStackTimersStart, *other.mStackTimers);
mMeasurements.write()->mergeSamples(*other.mMeasurements);
mRates.write()->mergeDeltas(*baseline.mRates, *target.mRates);
mStackTimers.write()->mergeDeltas(*baseline.mStackTimers, *target.mStackTimers);
}

View File

@ -57,8 +57,7 @@ namespace LLTrace
void resume();
void mergeSamples(const Recording& other);
void initDeltas(const Recording& other);
void mergeDeltas(const Recording& other);
void mergeDeltas(const Recording& baseline, const Recording& target);
void reset();
@ -80,10 +79,8 @@ namespace LLTrace
// returns data for current thread
class ThreadRecorder* getThreadRecorder();
LLCopyOnWritePointer<AccumulatorBuffer<RateAccumulator<F32> > > mRatesStart;
LLCopyOnWritePointer<AccumulatorBuffer<RateAccumulator<F32> > > mRates;
LLCopyOnWritePointer<AccumulatorBuffer<MeasurementAccumulator<F32> > > mMeasurements;
LLCopyOnWritePointer<AccumulatorBuffer<TimerAccumulator> > mStackTimersStart;
LLCopyOnWritePointer<AccumulatorBuffer<TimerAccumulator> > mStackTimers;
bool mIsStarted;