diff options
author | Richard Linden <none@none> | 2012-11-01 00:32:45 -0700 |
---|---|---|
committer | Richard Linden <none@none> | 2012-11-01 00:32:45 -0700 |
commit | 3ccbce90e37b92d5b32a2507804adc91bc58065d (patch) | |
tree | 519ae7f820bc8adde6617736c9d35c82c152705b /indra/llcommon | |
parent | b71e991c1860bbea0387f9434cc2b4b31a26469a (diff) | |
parent | 819adb5eb4d7f982121f3dbd82750e05d26864d9 (diff) |
Automated merge with ssh://hg.lindenlab.com/richard/viewer-interesting-metrics
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/CMakeLists.txt | 2 | ||||
-rw-r--r-- | indra/llcommon/llinstancetracker.h | 10 | ||||
-rw-r--r-- | indra/llcommon/llmetricperformancetester.cpp | 1 | ||||
-rw-r--r-- | indra/llcommon/llstat.cpp | 352 | ||||
-rw-r--r-- | indra/llcommon/llstat.h | 103 | ||||
-rw-r--r-- | indra/llcommon/lltrace.h | 90 | ||||
-rw-r--r-- | indra/llcommon/lltracerecording.cpp | 119 | ||||
-rw-r--r-- | indra/llcommon/lltracerecording.h | 216 | ||||
-rw-r--r-- | indra/llcommon/lltracethreadrecorder.cpp | 4 |
9 files changed, 315 insertions, 582 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index d876842cf1..0f5ded86ed 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -91,7 +91,6 @@ set(llcommon_SOURCE_FILES llsdutil.cpp llsecondlifeurls.cpp llsingleton.cpp - llstat.cpp llstacktrace.cpp llstreamqueue.cpp llstreamtools.cpp @@ -234,7 +233,6 @@ set(llcommon_HEADER_FILES llsortedvector.h llstack.h llstacktrace.h - llstat.h llstatenums.h llstl.h llstreamqueue.h diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 403df08990..3a1187a4c1 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -77,8 +77,8 @@ protected: /// This mix-in class adds support for tracking all instances of the specified class parameter T /// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup /// If KEY is not provided, then instances are stored in a simple set -/// @NOTE: see explicit specialization below for default KEY==T* case -template<typename T, typename KEY = T*> +/// @NOTE: see explicit specialization below for default KEY==void case +template<typename T, typename KEY = void> class LLInstanceTracker : public LLInstanceTrackerBase { typedef LLInstanceTracker<T, KEY> MyT; @@ -224,12 +224,12 @@ private: KEY mInstanceKey; }; -/// explicit specialization for default case where KEY is T* +/// explicit specialization for default case where KEY is void /// use a simple std::set<T*> template<typename T> -class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase +class LLInstanceTracker<T, void> : public LLInstanceTrackerBase { - typedef LLInstanceTracker<T, T*> MyT; + typedef LLInstanceTracker<T, void> MyT; typedef typename std::set<T*> InstanceSet; struct StaticData: public StaticBase { diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp index 41d3eb0bf3..a1b0a684c5 100644 --- a/indra/llcommon/llmetricperformancetester.cpp +++ b/indra/llcommon/llmetricperformancetester.cpp @@ -29,7 +29,6 @@ #include "indra_constants.h" #include "llerror.h" #include "llsdserialize.h" -#include "llstat.h" #include "lltreeiterators.h" #include "llmetricperformancetester.h" diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp deleted file mode 100644 index b46d2e58b2..0000000000 --- a/indra/llcommon/llstat.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/** - * @file llstat.cpp - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "llstat.h" -#include "lllivefile.h" -#include "llerrorcontrol.h" -#include "llframetimer.h" -#include "timing.h" -#include "llsd.h" -#include "llsdserialize.h" -#include "llstl.h" -#include "u64.h" - - -// statics -//------------------------------------------------------------------------ -LLTimer LLStat::sTimer; -LLFrameTimer LLStat::sFrameTimer; - -void LLStat::reset() -{ - mNumValues = 0; - mLastValue = 0.f; - delete[] mBins; - mBins = new ValueEntry[mNumBins]; - mCurBin = mNumBins-1; - mNextBin = 0; -} - -LLStat::LLStat(std::string name, BOOL use_frame_timer) -: LLInstanceTracker<LLStat, std::string>(name), - mUseFrameTimer(use_frame_timer), - mNumBins(50), - mName(name), - mBins(NULL) -{ - llassert(mNumBins > 0); - mLastTime = 0.f; - - reset(); -} - -LLStat::~LLStat() -{ - delete[] mBins; -} -// -//void LLStat::start() -//{ -// if (mUseFrameTimer) -// { -// mBins[mNextBin].mBeginTime = sFrameTimer.getElapsedSeconds(); -// } -// else -// { -// mBins[mNextBin].mBeginTime = sTimer.getElapsedTimeF64(); -// } -//} - -void LLStat::addValue(const F32 value) -{ - if (mNumValues < mNumBins) - { - mNumValues++; - } - - // Increment the bin counters. - mCurBin++; - if (mCurBin >= mNumBins) - { - mCurBin = 0; - } - mNextBin++; - if (mNextBin >= mNumBins) - { - mNextBin = 0; - } - - mBins[mCurBin].mValue = value; - if (mUseFrameTimer) - { - mBins[mCurBin].mTime = sFrameTimer.getElapsedSeconds(); - } - else - { - mBins[mCurBin].mTime = sTimer.getElapsedTimeF64(); - } - mBins[mCurBin].mDT = (F32)(mBins[mCurBin].mTime - mBins[mCurBin].mBeginTime); - - //this value is used to prime the min/max calls - mLastTime = mBins[mCurBin].mTime; - mLastValue = value; - - // Set the begin time for the next stat segment. - mBins[mNextBin].mBeginTime = mBins[mCurBin].mTime; - mBins[mNextBin].mTime = mBins[mCurBin].mTime; - mBins[mNextBin].mDT = 0.f; -} - - -F32 LLStat::getMax() const -{ - S32 i; - F32 current_max = mLastValue; - if (mNumBins == 0) - { - current_max = 0.f; - } - else - { - for (i = 0; (i < mNumBins) && (i < mNumValues); i++) - { - // Skip the bin we're currently filling. - if (i == mNextBin) - { - continue; - } - if (mBins[i].mValue > current_max) - { - current_max = mBins[i].mValue; - } - } - } - return current_max; -} - -F32 LLStat::getMean() const -{ - S32 i; - F32 current_mean = 0.f; - S32 samples = 0; - for (i = 0; (i < mNumBins) && (i < mNumValues); i++) - { - // Skip the bin we're currently filling. - if (i == mNextBin) - { - continue; - } - current_mean += mBins[i].mValue; - samples++; - } - - // There will be a wrap error at 2^32. :) - if (samples != 0) - { - current_mean /= samples; - } - else - { - current_mean = 0.f; - } - return current_mean; -} - -F32 LLStat::getMin() const -{ - S32 i; - F32 current_min = mLastValue; - - if (mNumBins == 0) - { - current_min = 0.f; - } - else - { - for (i = 0; (i < mNumBins) && (i < mNumValues); i++) - { - // Skip the bin we're currently filling. - if (i == mNextBin) - { - continue; - } - if (mBins[i].mValue < current_min) - { - current_min = mBins[i].mValue; - } - } - } - return current_min; -} - -F32 LLStat::getPrev(S32 age) const -{ - S32 bin; - bin = mCurBin - age; - - while (bin < 0) - { - bin += mNumBins; - } - - if (bin == mNextBin) - { - // Bogus for bin we're currently working on. - return 0.f; - } - return mBins[bin].mValue; -} - -F32 LLStat::getPrevPerSec(S32 age) const -{ - S32 bin; - bin = mCurBin - age; - - while (bin < 0) - { - bin += mNumBins; - } - - if (bin == mNextBin) - { - // Bogus for bin we're currently working on. - return 0.f; - } - return mBins[bin].mValue / mBins[bin].mDT; -} - -F32 LLStat::getCurrent() const -{ - return mBins[mCurBin].mValue; -} - -F32 LLStat::getCurrentPerSec() const -{ - return mBins[mCurBin].mValue / mBins[mCurBin].mDT; -} - -F32 LLStat::getMeanPerSec() const -{ - S32 i; - F32 value = 0.f; - F32 dt = 0.f; - - for (i = 0; (i < mNumBins) && (i < mNumValues); i++) - { - // Skip the bin we're currently filling. - if (i == mNextBin) - { - continue; - } - value += mBins[i].mValue; - dt += mBins[i].mDT; - } - - if (dt > 0.f) - { - return value/dt; - } - else - { - return 0.f; - } -} - -F32 LLStat::getMaxPerSec() const -{ - F32 value; - - if (mNextBin != 0) - { - value = mBins[0].mValue/mBins[0].mDT; - } - else if (mNumValues > 0) - { - value = mBins[1].mValue/mBins[1].mDT; - } - else - { - value = 0.f; - } - - for (S32 i = 0; (i < mNumBins) && (i < mNumValues); i++) - { - // Skip the bin we're currently filling. - if (i == mNextBin) - { - continue; - } - value = llmax(value, mBins[i].mValue/mBins[i].mDT); - } - return value; -} - -F32 LLStat::getMinPerSec() const -{ - S32 i; - F32 value; - - if (mNextBin != 0) - { - value = mBins[0].mValue/mBins[0].mDT; - } - else if (mNumValues > 0) - { - value = mBins[1].mValue/mBins[0].mDT; - } - else - { - value = 0.f; - } - - for (i = 0; (i < mNumBins) && (i < mNumValues); i++) - { - // Skip the bin we're currently filling. - if (i == mNextBin) - { - continue; - } - value = llmin(value, mBins[i].mValue/mBins[i].mDT); - } - return value; -} - -U32 LLStat::getNumValues() const -{ - return mNumValues; -} - -S32 LLStat::getNumBins() const -{ - return mNumBins; -} - -S32 LLStat::getNextBin() const -{ - return mNextBin; -} - diff --git a/indra/llcommon/llstat.h b/indra/llcommon/llstat.h deleted file mode 100644 index 82a246275d..0000000000 --- a/indra/llcommon/llstat.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file llstat.h - * @brief Runtime statistics accumulation. - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLSTAT_H -#define LL_LLSTAT_H - -#include <map> - -#include "lltimer.h" -#include "llframetimer.h" -#include "llinstancetracker.h" - -class LLSD; - -// ---------------------------------------------------------------------------- -class LL_COMMON_API LLStat : public LLInstanceTracker<LLStat, std::string> -{ -public: - LLStat(std::string name = std::string(), BOOL use_frame_timer = FALSE); - ~LLStat(); - - //void start(); // Start the timer for the current "frame", otherwise uses the time tracked from - // the last addValue - void reset(); - void addValue(const F32 value = 1.f); // Adds the current value being tracked, and tracks the DT. - void addValue(const S32 value) { addValue((F32)value); } - void addValue(const U32 value) { addValue((F32)value); } - - S32 getNextBin() const; - - F32 getPrev(S32 age) const; // Age is how many "addValues" previously - zero is current - F32 getPrevPerSec(S32 age) const; // Age is how many "addValues" previously - zero is current - - F32 getCurrent() const; - F32 getCurrentPerSec() const; - - F32 getMin() const; - F32 getMinPerSec() const; - - F32 getMean() const; - F32 getMeanPerSec() const; - - F32 getMax() const; - F32 getMaxPerSec() const; - - U32 getNumValues() const; - S32 getNumBins() const; - -private: - bool mUseFrameTimer; - U32 mNumValues; - U32 mNumBins; - F32 mLastValue; - F64 mLastTime; - - struct ValueEntry - { - ValueEntry() - : mValue(0.f), - mBeginTime(0.0), - mTime(0.0), - mDT(0.f) - {} - F32 mValue; - F64 mBeginTime; - F64 mTime; - F32 mDT; - }; - ValueEntry* mBins; - - S32 mCurBin; - S32 mNextBin; - - std::string mName; - - static LLTimer sTimer; - static LLFrameTimer sFrameTimer; -}; - -#endif // LL_STAT_ diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 2cdae4b0d2..2823db5cbb 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -227,10 +227,33 @@ namespace LLTrace }; + template<typename T, typename IS_UNIT = void> + struct StorageType + { + typedef T type_t; + }; + + template<typename T> + struct StorageType<T, typename T::is_unit_tag_t> + { + typedef typename StorageType<typename T::storage_t>::type_t type_t; + }; + + template<> struct StorageType<F32> { typedef F64 type_t; }; + template<> struct StorageType<S32> { typedef S64 type_t; }; + template<> struct StorageType<U32> { typedef S64 type_t; }; + template<> struct StorageType<S16> { typedef S64 type_t; }; + template<> struct StorageType<U16> { typedef S64 type_t; }; + template<> struct StorageType<S8> { typedef S64 type_t; }; + template<> struct StorageType<U8> { typedef S64 type_t; }; + template<typename T> class LL_COMMON_API MeasurementAccumulator { public: + typedef T value_t; + typedef MeasurementAccumulator<T> self_t; + MeasurementAccumulator() : mSum(0), mMin(std::numeric_limits<T>::max()), @@ -243,23 +266,24 @@ namespace LLTrace LL_FORCE_INLINE void sample(T value) { + T storage_value(value); mNumSamples++; - mSum += value; - if (value < mMin) + mSum += storage_value; + if (storage_value < mMin) { - mMin = value; + mMin = storage_value; } - else if (value > mMax) + if (storage_value > mMax) { - mMax = value; + mMax = storage_value; } F64 old_mean = mMean; - mMean += ((F64)value - old_mean) / (F64)mNumSamples; - mVarianceSum += ((F64)value - old_mean) * ((F64)value - mMean); - mLastValue = value; + mMean += ((F64)storage_value - old_mean) / (F64)mNumSamples; + mVarianceSum += ((F64)storage_value - old_mean) * ((F64)storage_value - mMean); + mLastValue = storage_value; } - void addSamples(const MeasurementAccumulator<T>& other) + void addSamples(const self_t& other) { mSum += other.mSum; if (other.mMin < mMin) @@ -293,7 +317,7 @@ namespace LLTrace } else { - mVarianceSum = (F32)mNumSamples + mVarianceSum = (F64)mNumSamples * ((((n_1 - 1.f) * sd_1 * sd_1) + ((n_2 - 1.f) * sd_2 * sd_2) + (((n_1 * n_2) / (n_1 + n_2)) @@ -311,10 +335,10 @@ namespace LLTrace mMax = 0; } - T getSum() const { return mSum; } - T getMin() const { return mMin; } - T getMax() const { return mMax; } - T getLastValue() const { return mLastValue; } + T getSum() const { return (T)mSum; } + T getMin() const { return (T)mMin; } + T getMax() const { return (T)mMax; } + T getLastValue() const { return (T)mLastValue; } F64 getMean() const { return mMean; } F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mNumSamples); } U32 getSampleCount() const { return mNumSamples; } @@ -325,7 +349,7 @@ namespace LLTrace mMax, mLastValue; - F64 mMean, + F64 mMean, mVarianceSum; U32 mNumSamples; @@ -335,6 +359,8 @@ namespace LLTrace class LL_COMMON_API CountAccumulator { public: + typedef T value_t; + CountAccumulator() : mSum(0), mNumSamples(0) @@ -358,7 +384,7 @@ namespace LLTrace mSum = 0; } - T getSum() const { return mSum; } + T getSum() const { return (T)mSum; } private: T mSum; @@ -366,14 +392,15 @@ namespace LLTrace U32 mNumSamples; }; - typedef TraceType<MeasurementAccumulator<F64> > measurement_common_t; + typedef TraceType<MeasurementAccumulator<F64> > measurement_common_float_t; + typedef TraceType<MeasurementAccumulator<S64> > measurement_common_int_t; template <typename T = F64, typename IS_UNIT = void> class LL_COMMON_API Measurement - : public TraceType<MeasurementAccumulator<T> > + : public TraceType<MeasurementAccumulator<typename StorageType<T>::type_t> > { public: - typedef T storage_t; + typedef typename StorageType<T>::type_t storage_t; Measurement(const char* name, const char* description = NULL) : TraceType(name, description) @@ -381,17 +408,16 @@ namespace LLTrace void sample(T value) { - getPrimaryAccumulator().sample(value); + getPrimaryAccumulator().sample((storage_t)value); } }; template <typename T> class LL_COMMON_API Measurement <T, typename T::is_unit_tag_t> - : public TraceType<MeasurementAccumulator<typename T::storage_t> > + : public TraceType<MeasurementAccumulator<typename StorageType<typename T::storage_t>::type_t> > { public: - typedef typename T::storage_t storage_t; - typedef Measurement<typename T::storage_t> base_measurement_t; + typedef typename StorageType<typename T::storage_t>::type_t storage_t; Measurement(const char* name, const char* description = NULL) : TraceType(name, description) @@ -402,18 +428,19 @@ namespace LLTrace { T converted_value; converted_value.assignFrom(value); - getPrimaryAccumulator().sample(converted_value.value()); + getPrimaryAccumulator().sample((storage_t)converted_value.value()); } }; - typedef TraceType<CountAccumulator<F64> > count_common_t; + typedef TraceType<CountAccumulator<F64> > count_common_float_t; + typedef TraceType<CountAccumulator<S64> > count_common_int_t; template <typename T = F64, typename IS_UNIT = void> class LL_COMMON_API Count - : public TraceType<CountAccumulator<T> > + : public TraceType<CountAccumulator<typename StorageType<T>::type_t> > { public: - typedef T storage_t; + typedef typename StorageType<T>::type_t storage_t; Count(const char* name, const char* description = NULL) : TraceType(name) @@ -421,17 +448,16 @@ namespace LLTrace void add(T value) { - getPrimaryAccumulator().add(value); + getPrimaryAccumulator().add((storage_t)value); } }; template <typename T> class LL_COMMON_API Count <T, typename T::is_unit_tag_t> - : public TraceType<CountAccumulator<typename T::storage_t> > + : public TraceType<CountAccumulator<typename StorageType<typename T::storage_t>::type_t> > { public: - typedef typename T::storage_t storage_t; - typedef Count<typename T::storage_t> base_count_t; + typedef typename StorageType<typename T::storage_t>::type_t storage_t; Count(const char* name, const char* description = NULL) : TraceType(name) @@ -442,7 +468,7 @@ namespace LLTrace { T converted_value; converted_value.assignFrom(value); - getPrimaryAccumulator().add(converted_value.value()); + getPrimaryAccumulator().add((storage_t)converted_value.value()); } }; diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index 9a769ff344..f44a0a2764 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -39,8 +39,10 @@ namespace LLTrace Recording::Recording() : mElapsedSeconds(0), - mCounts(new AccumulatorBuffer<CountAccumulator<F64> >()), - mMeasurements(new AccumulatorBuffer<MeasurementAccumulator<F64> >()), + mCountsFloat(new AccumulatorBuffer<CountAccumulator<F64> >()), + mMeasurementsFloat(new AccumulatorBuffer<MeasurementAccumulator<F64> >()), + mCounts(new AccumulatorBuffer<CountAccumulator<S64> >()), + mMeasurements(new AccumulatorBuffer<MeasurementAccumulator<S64> >()), mStackTimers(new AccumulatorBuffer<TimerAccumulator>()) {} @@ -59,6 +61,8 @@ void Recording::update() void Recording::handleReset() { + mCountsFloat.write()->reset(); + mMeasurementsFloat.write()->reset(); mCounts.write()->reset(); mMeasurements.write()->reset(); mStackTimers.write()->reset(); @@ -88,6 +92,8 @@ void Recording::handleSplitTo(Recording& other) void Recording::makePrimary() { + mCountsFloat.write()->makePrimary(); + mMeasurementsFloat.write()->makePrimary(); mCounts.write()->makePrimary(); mMeasurements.write()->makePrimary(); mStackTimers.write()->makePrimary(); @@ -100,14 +106,120 @@ bool Recording::isPrimary() const void Recording::mergeRecording( const Recording& other ) { + mCountsFloat.write()->addSamples(*other.mCountsFloat); + mMeasurementsFloat.write()->addSamples(*other.mMeasurementsFloat); mCounts.write()->addSamples(*other.mCounts); mMeasurements.write()->addSamples(*other.mMeasurements); mStackTimers.write()->addSamples(*other.mStackTimers); mElapsedSeconds += other.mElapsedSeconds; } +F64 Recording::getSum( const TraceType<CountAccumulator<F64> >& stat ) const +{ + return stat.getAccumulator(mCountsFloat).getSum(); +} + +S64 Recording::getSum( const TraceType<CountAccumulator<S64> >& stat ) const +{ + return stat.getAccumulator(mCounts).getSum(); +} + +F64 Recording::getSum( const TraceType<MeasurementAccumulator<F64> >& stat ) const +{ + return (F64)stat.getAccumulator(mMeasurementsFloat).getSum(); +} + +S64 Recording::getSum( const TraceType<MeasurementAccumulator<S64> >& stat ) const +{ + return (S64)stat.getAccumulator(mMeasurements).getSum(); +} + + + +F64 Recording::getPerSec( const TraceType<CountAccumulator<F64> >& stat ) const +{ + return stat.getAccumulator(mCountsFloat).getSum() / mElapsedSeconds; +} + +F64 Recording::getPerSec( const TraceType<CountAccumulator<S64> >& stat ) const +{ + return (F64)stat.getAccumulator(mCounts).getSum() / mElapsedSeconds; +} + +F64 Recording::getPerSec( const TraceType<MeasurementAccumulator<F64> >& stat ) const +{ + return stat.getAccumulator(mMeasurementsFloat).getSum() / mElapsedSeconds; +} + +F64 Recording::getPerSec( const TraceType<MeasurementAccumulator<S64> >& stat ) const +{ + return (F64)stat.getAccumulator(mMeasurements).getSum() / mElapsedSeconds; +} + +F64 Recording::getMin( const TraceType<MeasurementAccumulator<F64> >& stat ) const +{ + return stat.getAccumulator(mMeasurementsFloat).getMin(); +} + +S64 Recording::getMin( const TraceType<MeasurementAccumulator<S64> >& stat ) const +{ + return stat.getAccumulator(mMeasurements).getMin(); +} + +F64 Recording::getMax( const TraceType<MeasurementAccumulator<F64> >& stat ) const +{ + return stat.getAccumulator(mMeasurementsFloat).getMax(); +} + +S64 Recording::getMax( const TraceType<MeasurementAccumulator<S64> >& stat ) const +{ + return stat.getAccumulator(mMeasurements).getMax(); +} + +F64 Recording::getMean( const TraceType<MeasurementAccumulator<F64> >& stat ) const +{ + return stat.getAccumulator(mMeasurementsFloat).getMean(); +} + +F64 Recording::getMean( const TraceType<MeasurementAccumulator<S64> >& stat ) const +{ + return stat.getAccumulator(mMeasurements).getMean(); +} + +F64 Recording::getStandardDeviation( const TraceType<MeasurementAccumulator<F64> >& stat ) const +{ + return stat.getAccumulator(mMeasurementsFloat).getStandardDeviation(); +} + +F64 Recording::getStandardDeviation( const TraceType<MeasurementAccumulator<S64> >& stat ) const +{ + return stat.getAccumulator(mMeasurements).getStandardDeviation(); +} + +F64 Recording::getLastValue( const TraceType<MeasurementAccumulator<F64> >& stat ) const +{ + return stat.getAccumulator(mMeasurementsFloat).getLastValue(); +} + +S64 Recording::getLastValue( const TraceType<MeasurementAccumulator<S64> >& stat ) const +{ + return stat.getAccumulator(mMeasurements).getLastValue(); +} + +U32 Recording::getSampleCount( const TraceType<MeasurementAccumulator<F64> >& stat ) const +{ + return stat.getAccumulator(mMeasurementsFloat).getSampleCount(); +} + +U32 Recording::getSampleCount( const TraceType<MeasurementAccumulator<S64> >& stat ) const +{ + return stat.getAccumulator(mMeasurements).getSampleCount(); +} + + + /////////////////////////////////////////////////////////////////////// -// Recording +// PeriodicRecording /////////////////////////////////////////////////////////////////////// PeriodicRecording::PeriodicRecording( S32 num_periods ) @@ -179,6 +291,7 @@ void PeriodicRecording::handleSplitTo( PeriodicRecording& other ) getCurRecordingPeriod().handleSplitTo(other.getCurRecordingPeriod()); } + /////////////////////////////////////////////////////////////////////// // ExtendableRecording /////////////////////////////////////////////////////////////////////// diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index d3f001ab6a..4af973515d 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -112,124 +112,81 @@ namespace LLTrace void update(); // Count accessors + F64 getSum(const TraceType<CountAccumulator<F64> >& stat) const; + S64 getSum(const TraceType<CountAccumulator<S64> >& stat) const; template <typename T> - T getSum(const TraceType<CountAccumulator<T> >& stat) const + T getSum(const Count<T, typename T::is_unit_tag_t>& stat) const { - return (T)stat.getAccumulator(mCounts).getSum(); - } - - template <typename T, typename IS_UNIT> - T getSum(const Count<T, IS_UNIT>& stat) const - { - return (T)stat.getAccumulator(mCounts).getSum(); + return (T)getSum(static_cast<const TraceType<CountAccumulator<StorageType<T>::type_t> >&> (stat)); } + F64 getPerSec(const TraceType<CountAccumulator<F64> >& stat) const; + F64 getPerSec(const TraceType<CountAccumulator<S64> >& stat) const; template <typename T> - T getPerSec(const TraceType<CountAccumulator<T> >& stat) const + T getPerSec(const Count<T, typename T::is_unit_tag_t>& stat) const { - return (T)stat.getAccumulator(mCounts).getSum() / mElapsedSeconds; - } - - template <typename T, typename IS_UNIT> - T getPerSec(const Count<T, IS_UNIT>& stat) const - { - return (T)stat.getAccumulator(mCounts).getSum() / mElapsedSeconds; + return (T)getPerSec(static_cast<const TraceType<CountAccumulator<StorageType<T>::type_t> >&> (stat)); } // Measurement accessors + F64 getSum(const TraceType<MeasurementAccumulator<F64> >& stat) const; + S64 getSum(const TraceType<MeasurementAccumulator<S64> >& stat) const; template <typename T> - T getSum(const TraceType<MeasurementAccumulator<T> >& stat) const + T getSum(const Measurement<T, typename T::is_unit_tag_t>& stat) const { - return (T)stat.getAccumulator(mMeasurements).getSum(); - - } - - template <typename T, typename IS_UNIT> - T getSum(const Measurement<T, IS_UNIT>& stat) const - { - return (T)stat.getAccumulator(mMeasurements).getSum(); - + return (T)getSum(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat)); } + F64 getPerSec(const TraceType<MeasurementAccumulator<F64> >& stat) const; + F64 getPerSec(const TraceType<MeasurementAccumulator<S64> >& stat) const; template <typename T> - T getPerSec(const TraceType<MeasurementAccumulator<T> >& stat) const - { - return (T)stat.getAccumulator(mMeasurements).getSum() / mElapsedSeconds; - } - - template <typename T, typename IS_UNIT> - T getPerSec(const Measurement<T, IS_UNIT>& stat) const + T getPerSec(const Measurement<T, typename T::is_unit_tag_t>& stat) const { - return (typename Count<T, IS_UNIT>::base_unit_t)stat.getAccumulator(mMeasurements).getSum() / mElapsedSeconds; + return (T)getPerSec(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat)); } + F64 getMin(const TraceType<MeasurementAccumulator<F64> >& stat) const; + S64 getMin(const TraceType<MeasurementAccumulator<S64> >& stat) const; template <typename T> - T getMin(const TraceType<MeasurementAccumulator<T> >& stat) const - { - return (T)stat.getAccumulator(mMeasurements).getMin(); - } - - template <typename T, typename IS_UNIT> - T getMin(const Measurement<T, IS_UNIT>& stat) const + T getMin(const Measurement<T, typename T::is_unit_tag_t>& stat) const { - return (T)stat.getAccumulator(mMeasurements).getMin(); + return (T)getMin(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat)); } - + F64 getMax(const TraceType<MeasurementAccumulator<F64> >& stat) const; + S64 getMax(const TraceType<MeasurementAccumulator<S64> >& stat) const; template <typename T> - T getMax(const TraceType<MeasurementAccumulator<T> >& stat) const - { - return (T)stat.getAccumulator(mMeasurements).getMax(); - } - - template <typename T, typename IS_UNIT> - T getMax(const Measurement<T, IS_UNIT>& stat) const + T getMax(const Measurement<T, typename T::is_unit_tag_t>& stat) const { - return (T)stat.getAccumulator(mMeasurements).getMax(); + return (T)getMax(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat)); } + F64 getMean(const TraceType<MeasurementAccumulator<F64> >& stat) const; + F64 getMean(const TraceType<MeasurementAccumulator<S64> >& stat) const; template <typename T> - T getMean(const TraceType<MeasurementAccumulator<T> >& stat) const + T getMean(Measurement<T, typename T::is_unit_tag_t>& stat) const { - return (T)stat.getAccumulator(mMeasurements).getMean(); - } - - template <typename T, typename IS_UNIT> - T getMean(Measurement<T, IS_UNIT>& stat) const - { - return (T)stat.getAccumulator(mMeasurements).getMean(); + return (T)getMean(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat)); } + F64 getStandardDeviation(const TraceType<MeasurementAccumulator<F64> >& stat) const; + F64 getStandardDeviation(const TraceType<MeasurementAccumulator<S64> >& stat) const; template <typename T> - T getStandardDeviation(const TraceType<MeasurementAccumulator<T> >& stat) const - { - return (T)stat.getAccumulator(mMeasurements).getStandardDeviation(); - } - - template <typename T, typename IS_UNIT> - T getStandardDeviation(const Measurement<T, IS_UNIT>& stat) const + T getStandardDeviation(const Measurement<T, typename T::is_unit_tag_t>& stat) const { - return (T)stat.getAccumulator(mMeasurements).getStandardDeviation(); + return (T)getMean(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat)); } + F64 getLastValue(const TraceType<MeasurementAccumulator<F64> >& stat) const; + S64 getLastValue(const TraceType<MeasurementAccumulator<S64> >& stat) const; template <typename T> - T getLastValue(const TraceType<MeasurementAccumulator<T> >& stat) const - { - return (T)stat.getAccumulator(mMeasurements).getLastValue(); - } - - template <typename T, typename IS_UNIT> - T getLastValue(const Measurement<T, IS_UNIT>& stat) const + T getLastValue(const Measurement<T, typename T::is_unit_tag_t>& stat) const { - return (T)stat.getAccumulator(mMeasurements).getLastValue(); + return (T)getLastValue(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat)); } - - template <typename T> - U32 getSampleCount(const TraceType<MeasurementAccumulator<T> >& stat) const - { - return stat.getAccumulator(mMeasurements).getSampleCount(); - } + U32 getSampleCount(const TraceType<MeasurementAccumulator<F64> >& stat) const; + U32 getSampleCount(const TraceType<MeasurementAccumulator<S64> >& stat) const; LLUnit::Seconds<F64> getDuration() const { return mElapsedSeconds; } @@ -244,8 +201,10 @@ namespace LLTrace // returns data for current thread class ThreadRecorder* getThreadRecorder(); - LLCopyOnWritePointer<AccumulatorBuffer<CountAccumulator<F64> > > mCounts; - LLCopyOnWritePointer<AccumulatorBuffer<MeasurementAccumulator<F64> > > mMeasurements; + LLCopyOnWritePointer<AccumulatorBuffer<CountAccumulator<F64> > > mCountsFloat; + LLCopyOnWritePointer<AccumulatorBuffer<MeasurementAccumulator<F64> > > mMeasurementsFloat; + LLCopyOnWritePointer<AccumulatorBuffer<CountAccumulator<S64> > > mCounts; + LLCopyOnWritePointer<AccumulatorBuffer<MeasurementAccumulator<S64> > > mMeasurements; LLCopyOnWritePointer<AccumulatorBuffer<TimerAccumulator> > mStackTimers; LLTimer mSamplingTimer; @@ -260,6 +219,7 @@ namespace LLTrace ~PeriodicRecording(); void nextPeriod(); + S32 getNumPeriods() { return mNumPeriods; } Recording& getLastRecordingPeriod() { @@ -268,7 +228,7 @@ namespace LLTrace const Recording& getLastRecordingPeriod() const { - return mRecordingPeriods[(mCurPeriod + mNumPeriods - 1) % mNumPeriods]; + return getPrevRecordingPeriod(1); } Recording& getCurRecordingPeriod() @@ -281,6 +241,16 @@ namespace LLTrace return mRecordingPeriods[mCurPeriod]; } + Recording& getPrevRecordingPeriod(S32 offset) + { + return mRecordingPeriods[(mCurPeriod + mNumPeriods - offset) % mNumPeriods]; + } + + const Recording& getPrevRecordingPeriod(S32 offset) const + { + return mRecordingPeriods[(mCurPeriod + mNumPeriods - offset) % mNumPeriods]; + } + Recording snapshotCurRecordingPeriod() const { Recording recording_copy(getCurRecordingPeriod()); @@ -290,6 +260,84 @@ namespace LLTrace Recording& getTotalRecording(); + template <typename T> + typename T getPeriodMin(const TraceType<CountAccumulator<T> >& stat) const + { + T min_val = std::numeric_limits<T>::max(); + for (S32 i = 0; i < mNumPeriods; i++) + { + min_val = llmin(min_val, mRecordingPeriods[i].getSum(stat)); + } + return (T)min_val; + } + + template <typename T> + F64 getPeriodMinPerSec(const TraceType<CountAccumulator<T> >& stat) const + { + F64 min_val = std::numeric_limits<F64>::max(); + for (S32 i = 0; i < mNumPeriods; i++) + { + min_val = llmin(min_val, mRecordingPeriods[i].getPerSec(stat)); + } + return min_val; + } + + template <typename T> + T getPeriodMax(const TraceType<CountAccumulator<T> >& stat) const + { + T max_val = std::numeric_limits<T>::min(); + for (S32 i = 0; i < mNumPeriods; i++) + { + max_val = llmax(max_val, mRecordingPeriods[i].getSum(stat)); + } + return max_val; + } + + template <typename T> + F64 getPeriodMaxPerSec(const TraceType<CountAccumulator<T> >& stat) const + { + F64 max_val = std::numeric_limits<F64>::min(); + for (S32 i = 0; i < mNumPeriods; i++) + { + max_val = llmax(max_val, mRecordingPeriods[i].getPerSec(stat)); + } + return max_val; + } + + template <typename T> + F64 getPeriodMean(const TraceType<CountAccumulator<T> >& stat) const + { + F64 mean = 0.0; + F64 count = 0; + for (S32 i = 0; i < mNumPeriods; i++) + { + if (mRecordingPeriods[i].getDuration() > 0.f) + { + count++; + mean += mRecordingPeriods[i].getSum(stat); + } + } + mean /= (F64)mNumPeriods; + return mean; + } + + template <typename T> + F64 getPeriodMeanPerSec(const TraceType<CountAccumulator<T> >& stat) const + { + F64 mean = 0.0; + F64 count = 0; + for (S32 i = 0; i < mNumPeriods; i++) + { + if (mRecordingPeriods[i].getDuration() > 0.f) + { + count++; + mean += mRecordingPeriods[i].getPerSec(stat); + } + } + mean /= count; + return mean; + } + private: // implementation for LLVCRControlsMixin diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index e81333f7f2..15056b80e4 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -113,9 +113,13 @@ ThreadRecorder::ActiveRecording::ActiveRecording( Recording* target ) void ThreadRecorder::ActiveRecording::moveBaselineToTarget() { + mTargetRecording->mMeasurementsFloat.write()->addSamples(*mBaseline.mMeasurementsFloat); + mTargetRecording->mCountsFloat.write()->addSamples(*mBaseline.mCountsFloat); mTargetRecording->mMeasurements.write()->addSamples(*mBaseline.mMeasurements); mTargetRecording->mCounts.write()->addSamples(*mBaseline.mCounts); mTargetRecording->mStackTimers.write()->addSamples(*mBaseline.mStackTimers); + mBaseline.mMeasurementsFloat.write()->reset(); + mBaseline.mCountsFloat.write()->reset(); mBaseline.mMeasurements.write()->reset(); mBaseline.mCounts.write()->reset(); mBaseline.mStackTimers.write()->reset(); |