summaryrefslogtreecommitdiff
path: root/indra/llcommon/lltraceaccumulators.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/lltraceaccumulators.cpp')
-rw-r--r--indra/llcommon/lltraceaccumulators.cpp146
1 files changed, 136 insertions, 10 deletions
diff --git a/indra/llcommon/lltraceaccumulators.cpp b/indra/llcommon/lltraceaccumulators.cpp
index 950c1d97d1..a632f5634c 100644
--- a/indra/llcommon/lltraceaccumulators.cpp
+++ b/indra/llcommon/lltraceaccumulators.cpp
@@ -86,21 +86,21 @@ bool AccumulatorBufferGroup::isPrimary() const
void AccumulatorBufferGroup::append( const AccumulatorBufferGroup& other )
{
- mCounts.addSamples(other.mCounts);
- mSamples.addSamples(other.mSamples);
- mEvents.addSamples(other.mEvents);
- mMemStats.addSamples(other.mMemStats);
- mStackTimers.addSamples(other.mStackTimers);
+ mCounts.addSamples(other.mCounts, SEQUENTIAL);
+ mSamples.addSamples(other.mSamples, SEQUENTIAL);
+ mEvents.addSamples(other.mEvents, SEQUENTIAL);
+ mMemStats.addSamples(other.mMemStats, SEQUENTIAL);
+ mStackTimers.addSamples(other.mStackTimers, SEQUENTIAL);
}
void AccumulatorBufferGroup::merge( const AccumulatorBufferGroup& other)
{
- mCounts.addSamples(other.mCounts, false);
- mSamples.addSamples(other.mSamples, false);
- mEvents.addSamples(other.mEvents, false);
- mMemStats.addSamples(other.mMemStats, false);
+ mCounts.addSamples(other.mCounts, NON_SEQUENTIAL);
+ mSamples.addSamples(other.mSamples, NON_SEQUENTIAL);
+ mEvents.addSamples(other.mEvents, NON_SEQUENTIAL);
+ mMemStats.addSamples(other.mMemStats, NON_SEQUENTIAL);
// for now, hold out timers from merge, need to be displayed per thread
- //mStackTimers.addSamples(other.mStackTimers, false);
+ //mStackTimers.addSamples(other.mStackTimers, NON_SEQUENTIAL);
}
void AccumulatorBufferGroup::reset(AccumulatorBufferGroup* other)
@@ -120,4 +120,130 @@ void AccumulatorBufferGroup::sync()
mMemStats.sync(time_stamp);
}
+void SampleAccumulator::addSamples( const SampleAccumulator& other, EBufferAppendType append_type )
+{
+ if (!mHasValue)
+ {
+ *this = other;
+
+ if (append_type == NON_SEQUENTIAL)
+ {
+ // restore own last value state
+ mLastValue = NaN;
+ mHasValue = false;
+ }
+ }
+ else if (other.mHasValue)
+ {
+ mSum += other.mSum;
+
+ if (other.mMin < mMin) { mMin = other.mMin; }
+ if (other.mMax > mMax) { mMax = other.mMax; }
+
+ F64 epsilon = 0.0000001;
+
+ if (other.mTotalSamplingTime > epsilon)
+ {
+ // combine variance (and hence standard deviation) of 2 different sized sample groups using
+ // the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm
+ F64 n_1 = mTotalSamplingTime,
+ n_2 = other.mTotalSamplingTime;
+ F64 m_1 = mMean,
+ m_2 = other.mMean;
+ F64 v_1 = mSumOfSquares / mTotalSamplingTime,
+ v_2 = other.mSumOfSquares / other.mTotalSamplingTime;
+ if (n_1 < epsilon)
+ {
+ mSumOfSquares = other.mSumOfSquares;
+ }
+ else
+ {
+ mSumOfSquares = mTotalSamplingTime
+ * ((((n_1 - epsilon) * v_1)
+ + ((n_2 - epsilon) * v_2)
+ + (((n_1 * n_2) / (n_1 + n_2))
+ * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2))))
+ / (n_1 + n_2 - epsilon));
+ }
+
+ llassert(other.mTotalSamplingTime > 0);
+ F64 weight = mTotalSamplingTime / (mTotalSamplingTime + other.mTotalSamplingTime);
+ mNumSamples += other.mNumSamples;
+ mTotalSamplingTime += other.mTotalSamplingTime;
+ mMean = (mMean * weight) + (other.mMean * (1.0 - weight));
+ }
+ if (append_type == SEQUENTIAL)
+ {
+ mLastValue = other.mLastValue;
+ mLastSampleTimeStamp = other.mLastSampleTimeStamp;
+ mHasValue = true;
+ }
+ }
+}
+
+void SampleAccumulator::reset( const SampleAccumulator* other )
+{
+ mLastValue = other ? other->mLastValue : NaN;
+ mHasValue = other ? other->mHasValue : false;
+ mNumSamples = 0;
+ mSum = 0;
+ mMin = mLastValue;
+ mMax = mLastValue;
+ mMean = mLastValue;
+ mSumOfSquares = 0;
+ mLastSampleTimeStamp = LLTimer::getTotalSeconds();
+ mTotalSamplingTime = 0;
+}
+
+void EventAccumulator::addSamples( const EventAccumulator& other, EBufferAppendType append_type )
+{
+ if (other.mNumSamples)
+ {
+ if (!mNumSamples)
+ {
+ *this = other;
+ }
+ else
+ {
+ mSum += other.mSum;
+
+ // NOTE: both conditions will hold first time through
+ if (other.mMin < mMin) { mMin = other.mMin; }
+ if (other.mMax > mMax) { mMax = other.mMax; }
+
+ // combine variance (and hence standard deviation) of 2 different sized sample groups using
+ // the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm
+ F64 n_1 = (F64)mNumSamples,
+ n_2 = (F64)other.mNumSamples;
+ F64 m_1 = mMean,
+ m_2 = other.mMean;
+ F64 v_1 = mSumOfSquares / mNumSamples,
+ v_2 = other.mSumOfSquares / other.mNumSamples;
+ mSumOfSquares = (F64)mNumSamples
+ * ((((n_1 - 1.f) * v_1)
+ + ((n_2 - 1.f) * v_2)
+ + (((n_1 * n_2) / (n_1 + n_2))
+ * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2))))
+ / (n_1 + n_2 - 1.f));
+
+ F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples);
+ mNumSamples += other.mNumSamples;
+ mMean = mMean * weight + other.mMean * (1.f - weight);
+ if (append_type == SEQUENTIAL) mLastValue = other.mLastValue;
+ }
+ }
+}
+
+void EventAccumulator::reset( const EventAccumulator* other )
+{
+ mNumSamples = 0;
+ mSum = NaN;
+ mMin = NaN;
+ mMax = NaN;
+ mMean = NaN;
+ mSumOfSquares = 0;
+ mLastValue = other ? other->mLastValue : NaN;
+}
+
+
}