From 62fcbb063a191fa4789145c3937e7bef6ce544bd Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 5 Sep 2012 18:49:28 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages first pass at LLTrace framework --- indra/llcommon/lltrace.h | 169 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 indra/llcommon/lltrace.h (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h new file mode 100644 index 0000000000..3d3ee18100 --- /dev/null +++ b/indra/llcommon/lltrace.h @@ -0,0 +1,169 @@ +/** + * @file lltrace.h + * @brief Runtime statistics accumulation. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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_LLTRACE_H +#define LL_LLTRACE_H + +namespace LLTrace +{ + class Stat + { + public: + Stat(const char* name) + : mName(name) + {} + void record() {} + void record(int value) {} + void record(float value) {} + private: + const std::string mName; + }; + + class BlockTimer + { + public: + BlockTimer(const char* name) + : mName(name) + {} + + struct Accumulator + { + U32 mSelfTimeCounter; + U32 mTotalTimeCounter; + U32 mCalls; + Accumulator* mParent; // info for caller timer + Accumulator* mLastCaller; // used to bootstrap tree construction + const BlockTimer* mTimer; // points to block timer associated with this storage + 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 + std::vector mChildren; // currently assumed child timers + }; + + struct RecorderHead + { + struct Recorder* mRecorder; + Accumulator* mAccumulator; + U32 mChildTime; + }; + + struct Recorder + { + LL_FORCE_INLINE Recorder(BlockTimer& block_timer) + : mLastHead(sRecorderHead) + { + mStartTime = getCPUClockCount32(); + Accumulator* accumulator = ???; // get per-thread accumulator + accumulator->mActiveCount++; + accumulator->mCalls++; + accumulator->mMoveUpTree |= (accumulator->mParent->mActiveCount == 0); + + // push new timer on stack + sRecorderHead->mRecorder = this; + sRecorderHead->mAccumulator = accumulator; + sRecorderHead->mChildTime = 0; + } + + LL_FORCE_INLINE ~Recorder() + { + U32 total_time = getCPUClockCount32() - mStartTime; + + Accumulator* accumulator = sRecorderHead->mAccumulator; + accumulator->mSelfTimeCounter += total_time- sRecorderHead.mChildTime; + accumulator->mTotalTimeCounter += total_time; + accumulator->mActiveCount--; + + accumulator->mLastCaller = mLastHead->mAccumulator; + mLastHead->mChildTime += total_time; + + // pop stack + sRecorderHead = mLastHead; + } + + AccumulatorHead mLastHead; + U32 mStartTime; + }; + + private: + U32 getCPUClockCount32() + { + 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; + } + + // return full timer value, *not* shifted by 8 bits + static U64 getCPUClockCount64() + { + 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; + } + + const std::string mName; + static RecorderHead* sRecorderHead; + }; + + BlockTimer::RecorderHead BlockTimer::sRecorderHead; + + class TimeInterval + { + public: + void start() {} + void stop() {} + void resume() {} + }; + + class SamplingTimeInterval + { + public: + void start() {} + void stop() {} + void resume() {} + }; + +} + +#define TOKEN_PASTE_ACTUAL(x, y) x##y +#define TOKEN_PASTE(x, y) TOKEN_PASTE_ACTUAL(x, y) +#define RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder TOKEN_PASTE(block_time_recorder, __COUNTER__)(block_timer); + +#endif // LL_LLTRACE_H -- cgit v1.2.3 From 6814906fec95aeb90dbc99605f74f241a72af12b Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 5 Sep 2012 18:54:26 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages build fix --- indra/llcommon/lltrace.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 3d3ee18100..6323091cb8 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -81,16 +81,16 @@ namespace LLTrace accumulator->mMoveUpTree |= (accumulator->mParent->mActiveCount == 0); // push new timer on stack - sRecorderHead->mRecorder = this; - sRecorderHead->mAccumulator = accumulator; - sRecorderHead->mChildTime = 0; + sRecorderHead.mRecorder = this; + sRecorderHead.mAccumulator = accumulator; + sRecorderHead.mChildTime = 0; } LL_FORCE_INLINE ~Recorder() { U32 total_time = getCPUClockCount32() - mStartTime; - Accumulator* accumulator = sRecorderHead->mAccumulator; + Accumulator* accumulator = sRecorderHead.mAccumulator; accumulator->mSelfTimeCounter += total_time- sRecorderHead.mChildTime; accumulator->mTotalTimeCounter += total_time; accumulator->mActiveCount--; -- cgit v1.2.3 From 2cdfb170216c798c637081b0e28ec8921f0b777b Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 5 Sep 2012 19:04:53 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages renamed some variables in lltrace --- indra/llcommon/lltrace.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 6323091cb8..f3ee90a721 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -51,18 +51,18 @@ namespace LLTrace struct Accumulator { - U32 mSelfTimeCounter; U32 mTotalTimeCounter; + U32 mChildTimeCounter; U32 mCalls; Accumulator* mParent; // info for caller timer Accumulator* mLastCaller; // used to bootstrap tree construction const BlockTimer* mTimer; // points to block timer associated with this storage - U16 mActiveCount; // number of timers with this ID active on stack + U8 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 std::vector mChildren; // currently assumed child timers }; - struct RecorderHead + struct RecorderStackEntry { struct Recorder* mRecorder; Accumulator* mAccumulator; @@ -72,7 +72,7 @@ namespace LLTrace struct Recorder { LL_FORCE_INLINE Recorder(BlockTimer& block_timer) - : mLastHead(sRecorderHead) + : mLastRecorder(sCurRecorder) { mStartTime = getCPUClockCount32(); Accumulator* accumulator = ???; // get per-thread accumulator @@ -81,28 +81,28 @@ namespace LLTrace accumulator->mMoveUpTree |= (accumulator->mParent->mActiveCount == 0); // push new timer on stack - sRecorderHead.mRecorder = this; - sRecorderHead.mAccumulator = accumulator; - sRecorderHead.mChildTime = 0; + sCurRecorder.mRecorder = this; + sCurRecorder.mAccumulator = accumulator; + sCurRecorder.mChildTime = 0; } LL_FORCE_INLINE ~Recorder() { U32 total_time = getCPUClockCount32() - mStartTime; - Accumulator* accumulator = sRecorderHead.mAccumulator; - accumulator->mSelfTimeCounter += total_time- sRecorderHead.mChildTime; + Accumulator* accumulator = sCurRecorder.mAccumulator; accumulator->mTotalTimeCounter += total_time; + accumulator->mChildTimeCounter += sCurRecorder.mChildTime; accumulator->mActiveCount--; - accumulator->mLastCaller = mLastHead->mAccumulator; - mLastHead->mChildTime += total_time; + accumulator->mLastCaller = mLastRecorder->mAccumulator; + mLastRecorder->mChildTime += total_time; // pop stack - sRecorderHead = mLastHead; + sCurRecorder = mLastRecorder; } - AccumulatorHead mLastHead; + RecorderStackEntry mLastRecorder; U32 mStartTime; }; @@ -139,10 +139,10 @@ namespace LLTrace } const std::string mName; - static RecorderHead* sRecorderHead; + static RecorderStackEntry* sCurRecorder; }; - BlockTimer::RecorderHead BlockTimer::sRecorderHead; + BlockTimer::RecorderStackEntry BlockTimer::sCurRecorder; class TimeInterval { -- cgit v1.2.3 From d18a3f395fb2b29dbf83092896a5ed5eb9f75f16 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 6 Sep 2012 17:18:12 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages lltrace cleanup --- indra/llcommon/lltrace.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index f3ee90a721..1d2dcff9b7 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -27,6 +27,8 @@ #ifndef LL_LLTRACE_H #define LL_LLTRACE_H +#include + namespace LLTrace { class Stat @@ -51,11 +53,11 @@ namespace LLTrace struct Accumulator { - U32 mTotalTimeCounter; - U32 mChildTimeCounter; - U32 mCalls; - Accumulator* mParent; // info for caller timer - Accumulator* mLastCaller; // used to bootstrap tree construction + U32 mTotalTimeCounter, + mChildTimeCounter, + mCalls; + Accumulator* mParent, // info for caller timer + mLastCaller; // used to bootstrap tree construction const BlockTimer* mTimer; // points to block timer associated with this storage U8 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 -- cgit v1.2.3 From 8d4ceab6a34d58c5f4235baa870eb88d86df30f3 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 6 Sep 2012 23:00:32 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages further development of lltrace (accumulator and storage classes) --- indra/llcommon/lltrace.h | 111 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 95 insertions(+), 16 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 1d2dcff9b7..c6940c12a2 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -27,28 +27,108 @@ #ifndef LL_LLTRACE_H #define LL_LLTRACE_H +#include "stdtypes.h" +#include "llpreprocessor.h" + #include +#include namespace LLTrace { - class Stat + //TODO figure out best way to do this and proper naming convention + + static + void init() + { + + } + + template + class Accumulator { public: - Stat(const char* name) - : mName(name) + Accumulator() + : mSum(), + mMin(), + mMax(), + mNumSamples(0) + {} + + void sample(T value) + { + mNumSamples++; + mSum += value; + if (value < mMin) + { + mMin = value; + } + else if (value > mMax) + { + mMax = value; + } + } + + private: + T mSum, + mMin, + mMax; + + U32 mNumSamples; + }; + + class TraceStorage + { + protected: + TraceStorage(const size_t size, const size_t alignment) + { + mRecordOffset = sNextOffset + (alignment - 1); + mRecordOffset -= mRecordOffset % alignment; + sNextOffset = mRecordOffset + size; + sStorage.reserve((size_t)sNextOffset); + } + + // this needs to be thread local + static std::vector sStorage; + static ptrdiff_t sNextOffset; + + ptrdiff_t mRecordOffset; + }; + + std::vector TraceStorage::sStorage; + ptrdiff_t TraceStorage::sNextOffset = 0; + + template + class Trace : public TraceStorage + { + public: + Trace(const std::string& name) + : TraceStorage(sizeof(Accumulator), boost::alignment_of >::value), + mName(name) {} - void record() {} - void record(int value) {} - void record(float value) {} + + void record(T value) + { + (reinterpret_cast* >(sStorage + mRecordOffset))->sample(value); + } + private: - const std::string mName; + std::string mName; + }; + + template + class Stat : public Trace + { + public: + Stat(const char* name) + : Trace(name) + {} }; - class BlockTimer + class BlockTimer : public Trace { public: BlockTimer(const char* name) - : mName(name) + : Trace(name) {} struct Accumulator @@ -56,8 +136,8 @@ namespace LLTrace U32 mTotalTimeCounter, mChildTimeCounter, mCalls; - Accumulator* mParent, // info for caller timer - mLastCaller; // used to bootstrap tree construction + Accumulator* mParent; // info for caller timer + Accumulator* mLastCaller; // used to bootstrap tree construction const BlockTimer* mTimer; // points to block timer associated with this storage U8 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 @@ -97,8 +177,8 @@ namespace LLTrace accumulator->mChildTimeCounter += sCurRecorder.mChildTime; accumulator->mActiveCount--; - accumulator->mLastCaller = mLastRecorder->mAccumulator; - mLastRecorder->mChildTime += total_time; + accumulator->mLastCaller = mLastRecorder.mAccumulator; + mLastRecorder.mChildTime += total_time; // pop stack sCurRecorder = mLastRecorder; @@ -109,7 +189,7 @@ namespace LLTrace }; private: - U32 getCPUClockCount32() + static U32 getCPUClockCount32() { U32 ret_val; __asm @@ -140,8 +220,7 @@ namespace LLTrace return ret_val; } - const std::string mName; - static RecorderStackEntry* sCurRecorder; + static RecorderStackEntry sCurRecorder; }; BlockTimer::RecorderStackEntry BlockTimer::sCurRecorder; -- cgit v1.2.3 From a8c0d23bdeb009f6797f1dfa727e8c0cf4f6bc96 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 7 Sep 2012 18:51:38 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages created buffer type for storing trace data added merging logic for different trace types --- indra/llcommon/lltrace.h | 156 +++++++++++++++++++++++++++-------------------- 1 file changed, 90 insertions(+), 66 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index c6940c12a2..c5bde0330a 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -37,24 +37,57 @@ namespace LLTrace { //TODO figure out best way to do this and proper naming convention - static - void init() + static void init() { } + template + class Trace + { + public: + Trace(const std::string& name) + : mName(name) + { + mStorageIndex = sNextIndex++; + sStorage.reserve(sNextIndex); + } + + LL_FORCE_INLINE ACCUMULATOR& getAccumulator() + { + return sStorage[mStorageIndex]; + } + + void mergeFrom(const Trace& other) + { + getAccumulator().mergeFrom(other.getAccumulator()); + } + + + private: + std::string mName; + ptrdiff_t mStorageIndex; + + // this needs to be thread local + static std::vector sStorage; + static size_t sNextIndex; + }; + + template std::vector Trace::sStorage; + template size_t Trace::sNextIndex = 0; + template class Accumulator { public: Accumulator() - : mSum(), + : mSum(), mMin(), mMax(), mNumSamples(0) {} - void sample(T value) + LL_FORCE_INLINE void sample(T value) { mNumSamples++; mSum += value; @@ -68,6 +101,20 @@ namespace LLTrace } } + void mergeFrom(const Accumulator& other) + { + mSum += other.mSum; + if (other.mMin < mMin) + { + mMin = other.mMin; + } + if (other.mMax > mMax) + { + mMax = other.mMax; + } + mNumSamples += other.mNumSamples; + } + private: T mSum, mMin, @@ -76,78 +123,55 @@ namespace LLTrace U32 mNumSamples; }; - class TraceStorage - { - protected: - TraceStorage(const size_t size, const size_t alignment) - { - mRecordOffset = sNextOffset + (alignment - 1); - mRecordOffset -= mRecordOffset % alignment; - sNextOffset = mRecordOffset + size; - sStorage.reserve((size_t)sNextOffset); - } - - // this needs to be thread local - static std::vector sStorage; - static ptrdiff_t sNextOffset; - - ptrdiff_t mRecordOffset; - }; - - std::vector TraceStorage::sStorage; - ptrdiff_t TraceStorage::sNextOffset = 0; template - class Trace : public TraceStorage + class Stat : public Trace > { public: - Trace(const std::string& name) - : TraceStorage(sizeof(Accumulator), boost::alignment_of >::value), - mName(name) + Stat(const char* name) + : Trace(name) {} - void record(T value) + void sample(T value) { - (reinterpret_cast* >(sStorage + mRecordOffset))->sample(value); + getAccumulator().sample(value); } - private: - std::string mName; }; - template - class Stat : public Trace + struct TimerAccumulator { - public: - Stat(const char* name) - : Trace(name) - {} + U32 mTotalTimeCounter, + mChildTimeCounter, + mCalls; + TimerAccumulator* mParent; // info for caller timer + TimerAccumulator* mLastCaller; // used to bootstrap tree construction + const BlockTimer* mTimer; // points to block timer associated with this storage + U8 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 + std::vector mChildren; // currently assumed child timers + + void mergeFrom(const TimerAccumulator& other) + { + mTotalTimeCounter += other.mTotalTimeCounter; + mChildTimeCounter += other.mChildTimeCounter; + mCalls += other.mCalls; + } }; - class BlockTimer : public Trace + class BlockTimer : public Trace { public: BlockTimer(const char* name) : Trace(name) {} - struct Accumulator - { - U32 mTotalTimeCounter, - mChildTimeCounter, - mCalls; - Accumulator* mParent; // info for caller timer - Accumulator* mLastCaller; // used to bootstrap tree construction - const BlockTimer* mTimer; // points to block timer associated with this storage - U8 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 - std::vector mChildren; // currently assumed child timers - }; + struct Recorder; struct RecorderStackEntry { - struct Recorder* mRecorder; - Accumulator* mAccumulator; + Recorder* mRecorder; + TimerAccumulator* mAccumulator; U32 mChildTime; }; @@ -157,7 +181,7 @@ namespace LLTrace : mLastRecorder(sCurRecorder) { mStartTime = getCPUClockCount32(); - Accumulator* accumulator = ???; // get per-thread accumulator + TimerAccumulator* accumulator = &block_timer.getAccumulator(); // get per-thread accumulator accumulator->mActiveCount++; accumulator->mCalls++; accumulator->mMoveUpTree |= (accumulator->mParent->mActiveCount == 0); @@ -172,7 +196,7 @@ namespace LLTrace { U32 total_time = getCPUClockCount32() - mStartTime; - Accumulator* accumulator = sCurRecorder.mAccumulator; + TimerAccumulator* accumulator = sCurRecorder.mAccumulator; accumulator->mTotalTimeCounter += total_time; accumulator->mChildTimeCounter += sCurRecorder.mChildTime; accumulator->mActiveCount--; @@ -195,11 +219,11 @@ namespace LLTrace __asm { _emit 0x0f - _emit 0x31 - shr eax,8 - shl edx,24 - or eax, edx - mov dword ptr [ret_val], eax + _emit 0x31 + shr eax,8 + shl edx,24 + or eax, edx + mov dword ptr [ret_val], eax } return ret_val; } @@ -211,11 +235,11 @@ namespace LLTrace __asm { _emit 0x0f - _emit 0x31 - mov eax,eax - mov edx,edx - mov dword ptr [ret_val+4], edx - mov dword ptr [ret_val], eax + _emit 0x31 + mov eax,eax + mov edx,edx + mov dword ptr [ret_val+4], edx + mov dword ptr [ret_val], eax } return ret_val; } @@ -233,7 +257,7 @@ namespace LLTrace void resume() {} }; - class SamplingTimeInterval + class Sampler { public: void start() {} -- cgit v1.2.3 From fa91ea69cca32e0dabcfabe18070f57cc4a4cfd0 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 7 Sep 2012 19:12:41 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages added buffer merging and copying --- indra/llcommon/lltrace.h | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index c5bde0330a..6272492945 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -31,7 +31,6 @@ #include "llpreprocessor.h" #include -#include namespace LLTrace { @@ -42,6 +41,35 @@ namespace LLTrace } + template + struct AccumulatorStorage + { + std::vector mStorage; + + ACCUMULATOR& operator[](size_t index) { return mStorage[index]; } + + void mergeFrom(const AccumulatorStorage& other) + { + llassert(mStorage.size() == other.mStorage.size()); + + for (size_t i = 0; i < mStorage.size(); i++) + { + mStorage[i].mergeFrom(other.mStorage[i]); + } + } + + void copyFrom(const AccumulatorStorage& other) + { + mStorage = other.mStorage; + } + + void resize(size_t size) + { + //TODO: get this grow more rapidly (as if with push back) + mStorage.reserve(size); + } + }; + template class Trace { @@ -50,7 +78,7 @@ namespace LLTrace : mName(name) { mStorageIndex = sNextIndex++; - sStorage.reserve(sNextIndex); + sStorage.resize(sNextIndex); } LL_FORCE_INLINE ACCUMULATOR& getAccumulator() @@ -69,8 +97,8 @@ namespace LLTrace ptrdiff_t mStorageIndex; // this needs to be thread local - static std::vector sStorage; - static size_t sNextIndex; + static AccumulatorStorage sStorage; + static size_t sNextIndex; }; template std::vector Trace::sStorage; @@ -81,7 +109,7 @@ namespace LLTrace { public: Accumulator() - : mSum(), + : mSum(), mMin(), mMax(), mNumSamples(0) -- cgit v1.2.3 From 917ed449daec0e0f91e2ff66a7d9b82866ed8b1e Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 14 Sep 2012 00:04:38 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages added multi-threaded sampling to LLTrace first pass at data aggregation --- indra/llcommon/lltrace.h | 305 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 256 insertions(+), 49 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 6272492945..1b9a8db1c0 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -30,45 +30,90 @@ #include "stdtypes.h" #include "llpreprocessor.h" -#include +#include "llthread.h" + +#include namespace LLTrace { //TODO figure out best way to do this and proper naming convention - static void init() { } + // one per thread per type template - struct AccumulatorStorage + struct AccumulatorBuffer : public AccumulatorBufferBase { - std::vector mStorage; + ACCUMULATOR* mStorage; + size_t mStorageSize; + size_t mNextStorageSlot; + static S32 sStorageKey; // key used to access thread local storage pointer to accumulator values - ACCUMULATOR& operator[](size_t index) { return mStorage[index]; } + AccumulatorBuffer() + : mStorageSize(64), + mStorage(new ACCUMULATOR[64]), + mNextStorageSlot(0) + {} + + AccumulatorBuffer(const AccumulatorBuffer& other) + : mStorageSize(other.mStorageSize), + mStorage(new ACCUMULATOR[other.mStorageSize]), + mNextStorageSlot(other.mNextStorageSlot) + { + + } + + LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index) { return (*mStorage)[index]; } - void mergeFrom(const AccumulatorStorage& other) + void mergeFrom(const AccumulatorBuffer& other) { - llassert(mStorage.size() == other.mStorage.size()); + llassert(mNextStorageSlot == other.mNextStorageSlot); - for (size_t i = 0; i < mStorage.size(); i++) + for (size_t i = 0; i < mNextStorageSlot; i++) { mStorage[i].mergeFrom(other.mStorage[i]); } } - void copyFrom(const AccumulatorStorage& other) + void copyFrom(const AccumulatorBuffer& other) + { + for (size_t i = 0; i < mNextStorageSlot; i++) + { + mStorage[i] = other.mStorage[i]; + } + } + + void reset() + { + for (size_t i = 0; i < mNextStorageSlot; i++) + { + mStorage[i].reset(); + } + } + + void makePrimary() { - mStorage = other.mStorage; + //TODO: use sStorageKey to set mStorage as active buffer } - void resize(size_t size) + // NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned + size_t reserveSlot() { - //TODO: get this grow more rapidly (as if with push back) - mStorage.reserve(size); + size_t next_slot = mNextStorageSlot++; + if (next_slot >= mStorageSize) + { + size_t new_size = mStorageSize + (mStorageSize >> 2); + delete [] mStorage; + mStorage = new mStorage(new_size); + mStorageSize = new_size; + } + llassert(next_slot < mStorageSize); + return next_slot; } }; + template S32 AccumulatorBuffer::sStorageKey; template class Trace @@ -77,38 +122,29 @@ namespace LLTrace Trace(const std::string& name) : mName(name) { - mStorageIndex = sNextIndex++; - sStorage.resize(sNextIndex); + mAccumulatorIndex = sAccumulatorBuffer.reserveSlot(); } LL_FORCE_INLINE ACCUMULATOR& getAccumulator() { - return sStorage[mStorageIndex]; - } - - void mergeFrom(const Trace& other) - { - getAccumulator().mergeFrom(other.getAccumulator()); + return sAccumulatorBuffer[mAccumulatorIndex]; } - private: - std::string mName; - ptrdiff_t mStorageIndex; + std::string mName; + size_t mAccumulatorIndex; // this needs to be thread local - static AccumulatorStorage sStorage; - static size_t sNextIndex; + static AccumulatorBuffer sAccumulatorBuffer; }; - template std::vector Trace::sStorage; - template size_t Trace::sNextIndex = 0; + template std::vector Trace::sAccumulatorBuffer; template - class Accumulator + class StatAccumulator { public: - Accumulator() + StatAccumulator() : mSum(), mMin(), mMax(), @@ -129,7 +165,7 @@ namespace LLTrace } } - void mergeFrom(const Accumulator& other) + void mergeFrom(const Stat& other) { mSum += other.mSum; if (other.mMin < mMin) @@ -143,6 +179,14 @@ namespace LLTrace mNumSamples += other.mNumSamples; } + void reset() + { + mNumSamples = 0; + mSum = 0; + mMin = 0; + mMax = 0; + } + private: T mSum, mMin, @@ -151,12 +195,11 @@ namespace LLTrace U32 mNumSamples; }; - - template - class Stat : public Trace > + template + class Stat : public Trace > { public: - Stat(const char* name) + Stat(const std::string& name) : Trace(name) {} @@ -164,7 +207,6 @@ namespace LLTrace { getAccumulator().sample(value); } - }; struct TimerAccumulator @@ -174,7 +216,7 @@ namespace LLTrace mCalls; TimerAccumulator* mParent; // info for caller timer TimerAccumulator* mLastCaller; // used to bootstrap tree construction - const BlockTimer* mTimer; // points to block timer associated with this storage + const class BlockTimer* mTimer; // points to block timer associated with this storage U8 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 std::vector mChildren; // currently assumed child timers @@ -185,6 +227,14 @@ namespace LLTrace mChildTimeCounter += other.mChildTimeCounter; mCalls += other.mCalls; } + + void reset() + { + mTotalTimeCounter = 0; + mChildTimeCounter = 0; + mCalls = 0; + } + }; class BlockTimer : public Trace @@ -194,17 +244,15 @@ namespace LLTrace : Trace(name) {} - struct Recorder; - - struct RecorderStackEntry - { - Recorder* mRecorder; - TimerAccumulator* mAccumulator; - U32 mChildTime; - }; - struct Recorder { + struct StackEntry + { + Recorder* mRecorder; + TimerAccumulator* mAccumulator; + U32 mChildTime; + }; + LL_FORCE_INLINE Recorder(BlockTimer& block_timer) : mLastRecorder(sCurRecorder) { @@ -236,7 +284,7 @@ namespace LLTrace sCurRecorder = mLastRecorder; } - RecorderStackEntry mLastRecorder; + StackEntry mLastRecorder; U32 mStartTime; }; @@ -272,10 +320,169 @@ namespace LLTrace return ret_val; } - static RecorderStackEntry sCurRecorder; + static Recorder::StackEntry sCurRecorder; + }; + + BlockTimer::Recorder::StackEntry BlockTimer::sCurRecorder; + + class Sampler + { + public: + Sampler(const Sampler& other) + : mF32Stats(other.mF32Stats), + mS32Stats(other.mS32Stats), + mTimers(other.mTimers) + {} + + ~Sampler() + { + stop(); + } + + void makePrimary() + { + mF32Stats.makePrimary(); + mS32Stats.makePrimary(); + mTimers.makePrimary(); + } + + void start() + { + reset(); + resume(); + } + + void stop() + { + getThreadData()->deactivate(this); + } + + void resume() + { + ThreadData* thread_data = getThreadData(); + thread_data->flushPrimarySampler(); + thread_data->activate(this); + } + + void mergeFrom(const Sampler& other) + { + mF32Stats.mergeFrom(other.mF32Stats); + mS32Stats.mergeFrom(other.mS32Stats); + mTimers.mergeFrom(other.mTimers); + } + + void reset() + { + mF32Stats.reset(); + mS32Stats.reset(); + mTimers.reset(); + } + + private: + // returns data for current thread + struct ThreadData* getThreadData() { return NULL; } + + AccumulatorBuffer > mF32Stats; + AccumulatorBuffer > mS32Stats; + + AccumulatorBuffer mTimers; + }; + + struct ThreadData + { + ThreadData(LLThread& this_thread, ThreadData& parent_data) + : mPrimarySampler(parent_data.mPrimarySampler), + mSharedSampler(parent_data.mSharedSampler), + mSharedSamplerMutex(this_thread.getAPRPool()), + mParent(parent_data) + { + mPrimarySampler.makePrimary(); + parent_data.addChildThread(this); + } + + ~ThreadData() + { + mParent.removeChildThread(this); + } + + void addChildThread(ThreadData* child) + { + mChildThreadData.push_back(child); + } + + void removeChildThread(ThreadData* child) + { + // TODO: replace with intrusive list + std::list::iterator found_it = std::find(mChildThreadData.begin(), mChildThreadData.end(), child); + if (found_it != mChildThreadData.end()) + { + mChildThreadData.erase(found_it); + } + } + + void flushPrimarySampler() + { + for (std::list::iterator it = mActiveSamplers.begin(), end_it = mActiveSamplers.end(); + it != end_it; + ++it) + { + (*it)->mergeFrom(mPrimarySampler); + } + mPrimarySampler.reset(); + } + + void activate(Sampler* sampler) + { + mActiveSamplers.push_back(sampler); + } + + void deactivate(Sampler* sampler) + { + // TODO: replace with intrusive list + std::list::iterator found_it = std::find(mActiveSamplers.begin(), mActiveSamplers.end(), sampler); + if (found_it != mActiveSamplers.end()) + { + mActiveSamplers.erase(found_it); + } + } + + // call this periodically to gather stats data in parent thread + void publishToParent() + { + mSharedSamplerMutex.lock(); + { + mSharedSampler.mergeFrom(mPrimarySampler); + } + mSharedSamplerMutex.unlock(); + } + + // call this periodically to gather stats data from children + void gatherChildData() + { + for (std::list::iterator child_it = mChildThreadData.begin(), end_it = mChildThreadData.end(); + child_it != end_it; + ++child_it) + { + (*child_it)->mSharedSamplerMutex.lock(); + { + //TODO for now, just aggregate, later keep track of thread data independently + mPrimarySampler.mergeFrom((*child_it)->mSharedSampler); + } + (*child_it)->mSharedSamplerMutex.unlock(); + } + } + + Sampler mPrimarySampler; + + ThreadData& mParent; + std::list mActiveSamplers; + std::list mChildThreadData; + + // TODO: add unused space here to avoid false sharing? + LLMutex mSharedSamplerMutex; + Sampler mSharedSampler; }; - BlockTimer::RecorderStackEntry BlockTimer::sCurRecorder; class TimeInterval { -- cgit v1.2.3 From d5fce3a8093bb101b7a536f3611d3135167b05c4 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 14 Sep 2012 00:08:20 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages renamed some variables/methods --- indra/llcommon/lltrace.h | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 1b9a8db1c0..7da182df1e 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -36,11 +36,6 @@ namespace LLTrace { - //TODO figure out best way to do this and proper naming convention - static void init() - { - - } // one per thread per type template @@ -354,13 +349,13 @@ namespace LLTrace void stop() { - getThreadData()->deactivate(this); + getThreadTracer()->deactivate(this); } void resume() { - ThreadData* thread_data = getThreadData(); - thread_data->flushPrimarySampler(); + ThreadTracer* thread_data = getThreadTracer(); + thread_data->flushData(); thread_data->activate(this); } @@ -380,7 +375,7 @@ namespace LLTrace private: // returns data for current thread - struct ThreadData* getThreadData() { return NULL; } + struct ThreadTracer* getThreadTracer() { return NULL; } AccumulatorBuffer > mF32Stats; AccumulatorBuffer > mS32Stats; @@ -388,9 +383,9 @@ namespace LLTrace AccumulatorBuffer mTimers; }; - struct ThreadData + struct ThreadTracer { - ThreadData(LLThread& this_thread, ThreadData& parent_data) + ThreadTracer(LLThread& this_thread, ThreadTracer& parent_data) : mPrimarySampler(parent_data.mPrimarySampler), mSharedSampler(parent_data.mSharedSampler), mSharedSamplerMutex(this_thread.getAPRPool()), @@ -400,27 +395,27 @@ namespace LLTrace parent_data.addChildThread(this); } - ~ThreadData() + ~ThreadTracer() { mParent.removeChildThread(this); } - void addChildThread(ThreadData* child) + void addChildThread(ThreadTracer* child) { - mChildThreadData.push_back(child); + mChildThreadTracers.push_back(child); } - void removeChildThread(ThreadData* child) + void removeChildThread(ThreadTracer* child) { // TODO: replace with intrusive list - std::list::iterator found_it = std::find(mChildThreadData.begin(), mChildThreadData.end(), child); - if (found_it != mChildThreadData.end()) + std::list::iterator found_it = std::find(mChildThreadTracers.begin(), mChildThreadTracers.end(), child); + if (found_it != mChildThreadTracers.end()) { - mChildThreadData.erase(found_it); + mChildThreadTracers.erase(found_it); } } - void flushPrimarySampler() + void flushData() { for (std::list::iterator it = mActiveSamplers.begin(), end_it = mActiveSamplers.end(); it != end_it; @@ -459,7 +454,7 @@ namespace LLTrace // call this periodically to gather stats data from children void gatherChildData() { - for (std::list::iterator child_it = mChildThreadData.begin(), end_it = mChildThreadData.end(); + for (std::list::iterator child_it = mChildThreadTracers.begin(), end_it = mChildThreadTracers.end(); child_it != end_it; ++child_it) { @@ -474,9 +469,9 @@ namespace LLTrace Sampler mPrimarySampler; - ThreadData& mParent; - std::list mActiveSamplers; - std::list mChildThreadData; + ThreadTracer& mParent; + std::list mActiveSamplers; + std::list mChildThreadTracers; // TODO: add unused space here to avoid false sharing? LLMutex mSharedSamplerMutex; -- cgit v1.2.3 From 735fde8c742188d019e41faf26ff67aab6a24d25 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 21 Sep 2012 18:52:08 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages added LLThreadLocalPtr broke llmutex out into llmutex.h got primary sampling buffer under thread local storage --- indra/llcommon/lltrace.h | 265 +++++++++++++++++++++++++++-------------------- 1 file changed, 150 insertions(+), 115 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 7da182df1e..401ddfd6f3 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -30,25 +30,27 @@ #include "stdtypes.h" #include "llpreprocessor.h" -#include "llthread.h" +#include "llmutex.h" +#include "llmemory.h" +#include "llthreadlocalptr.h" #include +#define TOKEN_PASTE_ACTUAL(x, y) x##y +#define TOKEN_PASTE(x, y) TOKEN_PASTE_ACTUAL(x, y) +#define RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder TOKEN_PASTE(block_time_recorder, __COUNTER__)(block_timer); + namespace LLTrace { - // one per thread per type template - struct AccumulatorBuffer : public AccumulatorBufferBase + class AccumulatorBuffer { - ACCUMULATOR* mStorage; - size_t mStorageSize; - size_t mNextStorageSlot; - static S32 sStorageKey; // key used to access thread local storage pointer to accumulator values - + static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64; + public: AccumulatorBuffer() : mStorageSize(64), - mStorage(new ACCUMULATOR[64]), + mStorage(new ACCUMULATOR[DEFAULT_ACCUMULATOR_BUFFER_SIZE]), mNextStorageSlot(0) {} @@ -56,12 +58,13 @@ namespace LLTrace : mStorageSize(other.mStorageSize), mStorage(new ACCUMULATOR[other.mStorageSize]), mNextStorageSlot(other.mNextStorageSlot) - { + {} + LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index) + { + return mStorage[index]; } - LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index) { return (*mStorage)[index]; } - void mergeFrom(const AccumulatorBuffer& other) { llassert(mNextStorageSlot == other.mNextStorageSlot); @@ -72,7 +75,7 @@ namespace LLTrace } } - void copyFrom(const AccumulatorBuffer& other) + void copyFrom(const AccumulatorBuffer& other) { for (size_t i = 0; i < mNextStorageSlot; i++) { @@ -90,7 +93,12 @@ namespace LLTrace void makePrimary() { - //TODO: use sStorageKey to set mStorage as active buffer + sPrimaryStorage = mStorage; + } + + LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage() + { + return sPrimaryStorage.get(); } // NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned @@ -101,14 +109,29 @@ namespace LLTrace { size_t new_size = mStorageSize + (mStorageSize >> 2); delete [] mStorage; - mStorage = new mStorage(new_size); + mStorage = new ACCUMULATOR[new_size]; mStorageSize = new_size; } llassert(next_slot < mStorageSize); return next_slot; } + + private: + ACCUMULATOR* mStorage; + size_t mStorageSize; + size_t mNextStorageSlot; + static LLThreadLocalPtr sPrimaryStorage; + }; + template LLThreadLocalPtr AccumulatorBuffer::sPrimaryStorage; + + template + class PrimaryAccumulatorBuffer : public AccumulatorBuffer S32 AccumulatorBuffer::sStorageKey; template class Trace @@ -117,32 +140,34 @@ namespace LLTrace Trace(const std::string& name) : mName(name) { - mAccumulatorIndex = sAccumulatorBuffer.reserveSlot(); + mAccumulatorIndex = getPrimaryBuffer().reserveSlot(); } LL_FORCE_INLINE ACCUMULATOR& getAccumulator() { - return sAccumulatorBuffer[mAccumulatorIndex]; + return AccumulatorBuffer::getPrimaryStorage()[mAccumulatorIndex]; + } + + static PrimaryAccumulatorBuffer& getPrimaryBuffer() + { + static PrimaryAccumulatorBuffer sBuffer; + return sBuffer; } private: std::string mName; size_t mAccumulatorIndex; - - // this needs to be thread local - static AccumulatorBuffer sAccumulatorBuffer; }; - template std::vector Trace::sAccumulatorBuffer; template class StatAccumulator { public: StatAccumulator() - : mSum(), - mMin(), - mMax(), + : mSum(0), + mMin(0), + mMax(0), mNumSamples(0) {} @@ -160,7 +185,7 @@ namespace LLTrace } } - void mergeFrom(const Stat& other) + void mergeFrom(const StatAccumulator& other) { mSum += other.mSum; if (other.mMin < mMin) @@ -318,21 +343,13 @@ namespace LLTrace static Recorder::StackEntry sCurRecorder; }; - BlockTimer::Recorder::StackEntry BlockTimer::sCurRecorder; - class Sampler { public: - Sampler(const Sampler& other) - : mF32Stats(other.mF32Stats), - mS32Stats(other.mS32Stats), - mTimers(other.mTimers) - {} + Sampler() {} + Sampler(const Sampler& other); - ~Sampler() - { - stop(); - } + ~Sampler(); void makePrimary() { @@ -347,17 +364,8 @@ namespace LLTrace resume(); } - void stop() - { - getThreadTracer()->deactivate(this); - } - - void resume() - { - ThreadTracer* thread_data = getThreadTracer(); - thread_data->flushData(); - thread_data->activate(this); - } + void stop(); + void resume(); void mergeFrom(const Sampler& other) { @@ -375,7 +383,7 @@ namespace LLTrace private: // returns data for current thread - struct ThreadTracer* getThreadTracer() { return NULL; } + class ThreadTraceData* getThreadTrace(); AccumulatorBuffer > mF32Stats; AccumulatorBuffer > mS32Stats; @@ -383,39 +391,39 @@ namespace LLTrace AccumulatorBuffer mTimers; }; - struct ThreadTracer + class ThreadTraceData { - ThreadTracer(LLThread& this_thread, ThreadTracer& parent_data) - : mPrimarySampler(parent_data.mPrimarySampler), - mSharedSampler(parent_data.mSharedSampler), - mSharedSamplerMutex(this_thread.getAPRPool()), - mParent(parent_data) + public: + ThreadTraceData() { mPrimarySampler.makePrimary(); - parent_data.addChildThread(this); } - ~ThreadTracer() + ThreadTraceData(const ThreadTraceData& other) + : mPrimarySampler(other.mPrimarySampler) { - mParent.removeChildThread(this); + mPrimarySampler.makePrimary(); } - void addChildThread(ThreadTracer* child) + void activate(Sampler* sampler) { - mChildThreadTracers.push_back(child); + flushPrimary(); + mActiveSamplers.push_back(sampler); } - void removeChildThread(ThreadTracer* child) + void deactivate(Sampler* sampler) { + sampler->mergeFrom(mPrimarySampler); + // TODO: replace with intrusive list - std::list::iterator found_it = std::find(mChildThreadTracers.begin(), mChildThreadTracers.end(), child); - if (found_it != mChildThreadTracers.end()) + std::list::iterator found_it = std::find(mActiveSamplers.begin(), mActiveSamplers.end(), sampler); + if (found_it != mActiveSamplers.end()) { - mChildThreadTracers.erase(found_it); + mActiveSamplers.erase(found_it); } } - void flushData() + void flushPrimary() { for (std::list::iterator it = mActiveSamplers.begin(), end_it = mActiveSamplers.end(); it != end_it; @@ -426,56 +434,96 @@ namespace LLTrace mPrimarySampler.reset(); } - void activate(Sampler* sampler) + Sampler* getPrimarySampler() { return &mPrimarySampler; } + protected: + Sampler mPrimarySampler; + std::list mActiveSamplers; + static LLThreadLocalPtr sCurThreadTrace; + }; + + class MasterThreadTrace : public ThreadTraceData + { + public: + MasterThreadTrace() + {} + + void addSlaveThread(class SlaveThreadTrace* child); + void removeSlaveThread(class SlaveThreadTrace* child); + + // call this periodically to gather stats data from worker threads + void pullFromWorkerThreads(); + + private: + struct WorkerThreadTraceProxy { - mActiveSamplers.push_back(sampler); + WorkerThreadTraceProxy(class SlaveThreadTrace* trace) + : mWorkerTrace(trace) + {} + class SlaveThreadTrace* mWorkerTrace; + Sampler mSamplerStorage; + }; + typedef std::list worker_thread_trace_list_t; + + worker_thread_trace_list_t mSlaveThreadTraces; + LLMutex mSlaveListMutex; + }; + + class SlaveThreadTrace : public ThreadTraceData + { + public: + explicit + SlaveThreadTrace(MasterThreadTrace& master_trace) + : mMaster(master_trace), + ThreadTraceData(master_trace), + mSharedData(mPrimarySampler) + { + master_trace.addSlaveThread(this); } - void deactivate(Sampler* sampler) + ~SlaveThreadTrace() { - // TODO: replace with intrusive list - std::list::iterator found_it = std::find(mActiveSamplers.begin(), mActiveSamplers.end(), sampler); - if (found_it != mActiveSamplers.end()) - { - mActiveSamplers.erase(found_it); - } + mMaster.removeSlaveThread(this); } - - // call this periodically to gather stats data in parent thread - void publishToParent() + + // call this periodically to gather stats data for master thread to consume + void pushToParent() { - mSharedSamplerMutex.lock(); - { - mSharedSampler.mergeFrom(mPrimarySampler); - } - mSharedSamplerMutex.unlock(); + mSharedData.copyFrom(mPrimarySampler); } - // call this periodically to gather stats data from children - void gatherChildData() + MasterThreadTrace& mMaster; + + // this data is accessed by other threads, so give it a 64 byte alignment + // to avoid false sharing on most x86 processors + LL_ALIGNED(64) class SharedData { - for (std::list::iterator child_it = mChildThreadTracers.begin(), end_it = mChildThreadTracers.end(); - child_it != end_it; - ++child_it) + public: + explicit + SharedData(const Sampler& other_sampler) + : mSampler(other_sampler) + {} + + void copyFrom(Sampler& source) { - (*child_it)->mSharedSamplerMutex.lock(); - { - //TODO for now, just aggregate, later keep track of thread data independently - mPrimarySampler.mergeFrom((*child_it)->mSharedSampler); + LLMutexLock lock(&mSamplerMutex); + { + mSampler.mergeFrom(source); } - (*child_it)->mSharedSamplerMutex.unlock(); } - } - Sampler mPrimarySampler; - - ThreadTracer& mParent; - std::list mActiveSamplers; - std::list mChildThreadTracers; - - // TODO: add unused space here to avoid false sharing? - LLMutex mSharedSamplerMutex; - Sampler mSharedSampler; + void copyTo(Sampler& sink) + { + LLMutexLock lock(&mSamplerMutex); + { + sink.mergeFrom(mSampler); + } + } + private: + // add a cache line's worth of unused space to avoid any potential of false sharing + LLMutex mSamplerMutex; + Sampler mSampler; + }; + SharedData mSharedData; }; @@ -486,19 +534,6 @@ namespace LLTrace void stop() {} void resume() {} }; - - class Sampler - { - public: - void start() {} - void stop() {} - void resume() {} - }; - } -#define TOKEN_PASTE_ACTUAL(x, y) x##y -#define TOKEN_PASTE(x, y) TOKEN_PASTE_ACTUAL(x, y) -#define RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder TOKEN_PASTE(block_time_recorder, __COUNTER__)(block_timer); - #endif // LL_LLTRACE_H -- cgit v1.2.3 From adeeabfc13c91dc99a1ea1949cd2f820c4150995 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 24 Sep 2012 18:56:01 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages moved LLThreadLocalPtr to llapr fixed various startup race conditions for LLThreadLocalPtr --- indra/llcommon/lltrace.h | 57 +++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 27 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 401ddfd6f3..3af05d67f9 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -32,7 +32,6 @@ #include "llmutex.h" #include "llmemory.h" -#include "llthreadlocalptr.h" #include @@ -42,19 +41,29 @@ namespace LLTrace { + void init(); + void cleanup(); + + extern class MasterThreadTrace *gMasterThreadTrace; + extern LLThreadLocalPtr gCurThreadTrace; + // one per thread per type template class AccumulatorBuffer { static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64; - public: - AccumulatorBuffer() + private: + enum StaticAllocationMarker { STATIC_ALLOC }; + + AccumulatorBuffer(StaticAllocationMarker m) : mStorageSize(64), - mStorage(new ACCUMULATOR[DEFAULT_ACCUMULATOR_BUFFER_SIZE]), - mNextStorageSlot(0) - {} + mNextStorageSlot(0), + mStorage(new ACCUMULATOR[DEFAULT_ACCUMULATOR_BUFFER_SIZE]) + { + } + public: - AccumulatorBuffer(const AccumulatorBuffer& other) + AccumulatorBuffer(const AccumulatorBuffer& other = getDefaultBuffer()) : mStorageSize(other.mStorageSize), mStorage(new ACCUMULATOR[other.mStorageSize]), mNextStorageSlot(other.mNextStorageSlot) @@ -116,6 +125,12 @@ namespace LLTrace return next_slot; } + static AccumulatorBuffer& getDefaultBuffer() + { + static AccumulatorBuffer sBuffer; + return sBuffer; + } + private: ACCUMULATOR* mStorage; size_t mStorageSize; @@ -124,15 +139,6 @@ namespace LLTrace }; template LLThreadLocalPtr AccumulatorBuffer::sPrimaryStorage; - template - class PrimaryAccumulatorBuffer : public AccumulatorBuffer class Trace { @@ -140,7 +146,7 @@ namespace LLTrace Trace(const std::string& name) : mName(name) { - mAccumulatorIndex = getPrimaryBuffer().reserveSlot(); + mAccumulatorIndex = AccumulatorBuffer::getDefaultBuffer().reserveSlot(); } LL_FORCE_INLINE ACCUMULATOR& getAccumulator() @@ -148,12 +154,6 @@ namespace LLTrace return AccumulatorBuffer::getPrimaryStorage()[mAccumulatorIndex]; } - static PrimaryAccumulatorBuffer& getPrimaryBuffer() - { - static PrimaryAccumulatorBuffer sBuffer; - return sBuffer; - } - private: std::string mName; size_t mAccumulatorIndex; @@ -347,9 +347,13 @@ namespace LLTrace { public: Sampler() {} - Sampler(const Sampler& other); + Sampler(const Sampler& other) + : mF32Stats(other.mF32Stats), + mS32Stats(other.mS32Stats), + mTimers(other.mTimers) + {} - ~Sampler(); + ~Sampler() {} void makePrimary() { @@ -438,7 +442,6 @@ namespace LLTrace protected: Sampler mPrimarySampler; std::list mActiveSamplers; - static LLThreadLocalPtr sCurThreadTrace; }; class MasterThreadTrace : public ThreadTraceData @@ -472,7 +475,7 @@ namespace LLTrace { public: explicit - SlaveThreadTrace(MasterThreadTrace& master_trace) + SlaveThreadTrace(MasterThreadTrace& master_trace = *gMasterThreadTrace) : mMaster(master_trace), ThreadTraceData(master_trace), mSharedData(mPrimarySampler) -- cgit v1.2.3 From 05a3203d8274a0a0999faad128f629614b8d62c5 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 26 Sep 2012 17:04:57 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages fixed various issues related to unit tests and LLThreadLocalPtr initialization and teardown --- indra/llcommon/lltrace.h | 47 +++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 3af05d67f9..e4bec0a644 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -44,8 +44,7 @@ namespace LLTrace void init(); void cleanup(); - extern class MasterThreadTrace *gMasterThreadTrace; - extern LLThreadLocalPtr gCurThreadTrace; + class MasterThreadTrace& getMasterThreadTrace(); // one per thread per type template @@ -59,8 +58,8 @@ namespace LLTrace : mStorageSize(64), mNextStorageSlot(0), mStorage(new ACCUMULATOR[DEFAULT_ACCUMULATOR_BUFFER_SIZE]) - { - } + {} + public: AccumulatorBuffer(const AccumulatorBuffer& other = getDefaultBuffer()) @@ -69,6 +68,15 @@ namespace LLTrace mNextStorageSlot(other.mNextStorageSlot) {} + ~AccumulatorBuffer() + { + if (sPrimaryStorage == mStorage) + { + //TODO pick another primary? + sPrimaryStorage = NULL; + } + } + LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index) { return mStorage[index]; @@ -353,7 +361,8 @@ namespace LLTrace mTimers(other.mTimers) {} - ~Sampler() {} + ~Sampler() + {} void makePrimary() { @@ -453,21 +462,21 @@ namespace LLTrace void addSlaveThread(class SlaveThreadTrace* child); void removeSlaveThread(class SlaveThreadTrace* child); - // call this periodically to gather stats data from worker threads - void pullFromWorkerThreads(); + // call this periodically to gather stats data from slave threads + void pullFromSlaveThreads(); private: - struct WorkerThreadTraceProxy + struct SlaveThreadTraceProxy { - WorkerThreadTraceProxy(class SlaveThreadTrace* trace) - : mWorkerTrace(trace) + SlaveThreadTraceProxy(class SlaveThreadTrace* trace) + : mSlaveTrace(trace) {} - class SlaveThreadTrace* mWorkerTrace; + class SlaveThreadTrace* mSlaveTrace; Sampler mSamplerStorage; }; - typedef std::list worker_thread_trace_list_t; + typedef std::list slave_thread_trace_list_t; - worker_thread_trace_list_t mSlaveThreadTraces; + slave_thread_trace_list_t mSlaveThreadTraces; LLMutex mSlaveListMutex; }; @@ -475,17 +484,16 @@ namespace LLTrace { public: explicit - SlaveThreadTrace(MasterThreadTrace& master_trace = *gMasterThreadTrace) - : mMaster(master_trace), - ThreadTraceData(master_trace), + SlaveThreadTrace() + : ThreadTraceData(getMasterThreadTrace()), mSharedData(mPrimarySampler) { - master_trace.addSlaveThread(this); + getMasterThreadTrace().addSlaveThread(this); } ~SlaveThreadTrace() { - mMaster.removeSlaveThread(this); + getMasterThreadTrace().removeSlaveThread(this); } // call this periodically to gather stats data for master thread to consume @@ -494,7 +502,7 @@ namespace LLTrace mSharedData.copyFrom(mPrimarySampler); } - MasterThreadTrace& mMaster; + MasterThreadTrace* mMaster; // this data is accessed by other threads, so give it a 64 byte alignment // to avoid false sharing on most x86 processors @@ -529,7 +537,6 @@ namespace LLTrace SharedData mSharedData; }; - class TimeInterval { public: -- cgit v1.2.3 From 07c4be092b276f0d7c14ba12872efb31c1f16764 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 26 Sep 2012 19:12:40 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages slave threads now pushing data to master thread --- indra/llcommon/lltrace.h | 63 ++++++++++++------------------------------------ 1 file changed, 16 insertions(+), 47 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index e4bec0a644..601b5ed182 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -396,7 +396,7 @@ namespace LLTrace private: // returns data for current thread - class ThreadTraceData* getThreadTrace(); + class ThreadTrace* getThreadTrace(); AccumulatorBuffer > mF32Stats; AccumulatorBuffer > mS32Stats; @@ -404,48 +404,19 @@ namespace LLTrace AccumulatorBuffer mTimers; }; - class ThreadTraceData + class ThreadTrace { public: - ThreadTraceData() - { - mPrimarySampler.makePrimary(); - } - - ThreadTraceData(const ThreadTraceData& other) - : mPrimarySampler(other.mPrimarySampler) - { - mPrimarySampler.makePrimary(); - } + ThreadTrace(); + ThreadTrace(const ThreadTrace& other); - void activate(Sampler* sampler) - { - flushPrimary(); - mActiveSamplers.push_back(sampler); - } + virtual ~ThreadTrace() {} - void deactivate(Sampler* sampler) - { - sampler->mergeFrom(mPrimarySampler); - - // TODO: replace with intrusive list - std::list::iterator found_it = std::find(mActiveSamplers.begin(), mActiveSamplers.end(), sampler); - if (found_it != mActiveSamplers.end()) - { - mActiveSamplers.erase(found_it); - } - } + void activate(Sampler* sampler); + void deactivate(Sampler* sampler); + void flushPrimary(); - void flushPrimary() - { - for (std::list::iterator it = mActiveSamplers.begin(), end_it = mActiveSamplers.end(); - it != end_it; - ++it) - { - (*it)->mergeFrom(mPrimarySampler); - } - mPrimarySampler.reset(); - } + virtual void pushToMaster() = 0; Sampler* getPrimarySampler() { return &mPrimarySampler; } protected: @@ -453,15 +424,16 @@ namespace LLTrace std::list mActiveSamplers; }; - class MasterThreadTrace : public ThreadTraceData + class MasterThreadTrace : public ThreadTrace { public: - MasterThreadTrace() - {} + MasterThreadTrace(); void addSlaveThread(class SlaveThreadTrace* child); void removeSlaveThread(class SlaveThreadTrace* child); + /*virtual */ void pushToMaster(); + // call this periodically to gather stats data from slave threads void pullFromSlaveThreads(); @@ -480,12 +452,12 @@ namespace LLTrace LLMutex mSlaveListMutex; }; - class SlaveThreadTrace : public ThreadTraceData + class SlaveThreadTrace : public ThreadTrace { public: explicit SlaveThreadTrace() - : ThreadTraceData(getMasterThreadTrace()), + : ThreadTrace(getMasterThreadTrace()), mSharedData(mPrimarySampler) { getMasterThreadTrace().addSlaveThread(this); @@ -497,10 +469,7 @@ namespace LLTrace } // call this periodically to gather stats data for master thread to consume - void pushToParent() - { - mSharedData.copyFrom(mPrimarySampler); - } + /*virtual*/ void pushToMaster(); MasterThreadTrace* mMaster; -- cgit v1.2.3 From 38354e19063478c8cda0408547ad05023b457041 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 28 Sep 2012 10:45:14 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages created separate constructor for static allocation of sampler buffer fixed start/stop/resume semantics of samplers and added sampler time interval tracking --- indra/llcommon/lltrace.h | 108 ++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 62 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 601b5ed182..a443735e69 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -32,6 +32,7 @@ #include "llmutex.h" #include "llmemory.h" +#include "lltimer.h" #include @@ -39,6 +40,7 @@ #define TOKEN_PASTE(x, y) TOKEN_PASTE_ACTUAL(x, y) #define RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder TOKEN_PASTE(block_time_recorder, __COUNTER__)(block_timer); + namespace LLTrace { void init(); @@ -135,7 +137,7 @@ namespace LLTrace static AccumulatorBuffer& getDefaultBuffer() { - static AccumulatorBuffer sBuffer; + static AccumulatorBuffer sBuffer(STATIC_ALLOC); return sBuffer; } @@ -354,54 +356,38 @@ namespace LLTrace class Sampler { public: - Sampler() {} - Sampler(const Sampler& other) - : mF32Stats(other.mF32Stats), - mS32Stats(other.mS32Stats), - mTimers(other.mTimers) - {} - - ~Sampler() - {} + ~Sampler(); - void makePrimary() - { - mF32Stats.makePrimary(); - mS32Stats.makePrimary(); - mTimers.makePrimary(); - } - - void start() - { - reset(); - resume(); - } + void makePrimary(); + void start(); void stop(); void resume(); - void mergeFrom(const Sampler& other) - { - mF32Stats.mergeFrom(other.mF32Stats); - mS32Stats.mergeFrom(other.mS32Stats); - mTimers.mergeFrom(other.mTimers); - } + void mergeFrom(const Sampler* other); - void reset() - { - mF32Stats.reset(); - mS32Stats.reset(); - mTimers.reset(); - } + void reset(); + + bool isStarted() { return mIsStarted; } private: + friend class ThreadTrace; + Sampler(class ThreadTrace* thread_trace); + + // no copy + Sampler(const Sampler& other) {} // returns data for current thread class ThreadTrace* getThreadTrace(); AccumulatorBuffer > mF32Stats; AccumulatorBuffer > mS32Stats; - AccumulatorBuffer mTimers; + AccumulatorBuffer mStackTimers; + + bool mIsStarted; + LLTimer mSamplingTimer; + F64 mElapsedSeconds; + ThreadTrace* mThreadTrace; }; class ThreadTrace @@ -410,17 +396,19 @@ namespace LLTrace ThreadTrace(); ThreadTrace(const ThreadTrace& other); - virtual ~ThreadTrace() {} + virtual ~ThreadTrace(); void activate(Sampler* sampler); void deactivate(Sampler* sampler); void flushPrimary(); + Sampler* createSampler(); + virtual void pushToMaster() = 0; - Sampler* getPrimarySampler() { return &mPrimarySampler; } + Sampler* getPrimarySampler() { return mPrimarySampler; } protected: - Sampler mPrimarySampler; + Sampler* mPrimarySampler; std::list mActiveSamplers; }; @@ -440,11 +428,11 @@ namespace LLTrace private: struct SlaveThreadTraceProxy { - SlaveThreadTraceProxy(class SlaveThreadTrace* trace) - : mSlaveTrace(trace) - {} + SlaveThreadTraceProxy(class SlaveThreadTrace* trace, Sampler* storage); + + ~SlaveThreadTraceProxy(); class SlaveThreadTrace* mSlaveTrace; - Sampler mSamplerStorage; + Sampler* mSamplerStorage; }; typedef std::list slave_thread_trace_list_t; @@ -455,18 +443,8 @@ namespace LLTrace class SlaveThreadTrace : public ThreadTrace { public: - explicit - SlaveThreadTrace() - : ThreadTrace(getMasterThreadTrace()), - mSharedData(mPrimarySampler) - { - getMasterThreadTrace().addSlaveThread(this); - } - - ~SlaveThreadTrace() - { - getMasterThreadTrace().removeSlaveThread(this); - } + SlaveThreadTrace(); + ~SlaveThreadTrace(); // call this periodically to gather stats data for master thread to consume /*virtual*/ void pushToMaster(); @@ -479,29 +457,35 @@ namespace LLTrace { public: explicit - SharedData(const Sampler& other_sampler) - : mSampler(other_sampler) - {} + SharedData(Sampler* sampler) + : mSampler(sampler) + { + } + + ~SharedData() + { + delete mSampler; + } - void copyFrom(Sampler& source) + void copyFrom(Sampler* source) { LLMutexLock lock(&mSamplerMutex); { - mSampler.mergeFrom(source); + mSampler->mergeFrom(source); } } - void copyTo(Sampler& sink) + void copyTo(Sampler* sink) { LLMutexLock lock(&mSamplerMutex); { - sink.mergeFrom(mSampler); + sink->mergeFrom(mSampler); } } private: // add a cache line's worth of unused space to avoid any potential of false sharing LLMutex mSamplerMutex; - Sampler mSampler; + Sampler* mSampler; }; SharedData mSharedData; }; -- cgit v1.2.3 From b1baf982b1bd41a150233d0a28d3601226924c65 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sun, 30 Sep 2012 10:41:29 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages factored out lltrace::sampler into separate file added rudimentary lltrace support to llstatgraph made llstatgraph use param blocks more effectively moves initial set of stats over to lltrace removed windows.h #defines for min and max --- indra/llcommon/lltrace.h | 127 +++++++++++++++-------------------------------- 1 file changed, 40 insertions(+), 87 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index a443735e69..c6f920b5e4 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -43,14 +43,16 @@ namespace LLTrace { + class Sampler; + void init(); void cleanup(); - class MasterThreadTrace& getMasterThreadTrace(); + class LL_COMMON_API MasterThreadTrace& getMasterThreadTrace(); // one per thread per type template - class AccumulatorBuffer + class LL_COMMON_API AccumulatorBuffer { static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64; private: @@ -64,6 +66,8 @@ namespace LLTrace public: + // copying an accumulator buffer does not copy the actual contents, but simply initializes the buffer size + // to be identical to the other buffer AccumulatorBuffer(const AccumulatorBuffer& other = getDefaultBuffer()) : mStorageSize(other.mStorageSize), mStorage(new ACCUMULATOR[other.mStorageSize]), @@ -150,28 +154,30 @@ namespace LLTrace template LLThreadLocalPtr AccumulatorBuffer::sPrimaryStorage; template - class Trace + class LL_COMMON_API TraceType { public: - Trace(const std::string& name) + TraceType(const std::string& name) : mName(name) { mAccumulatorIndex = AccumulatorBuffer::getDefaultBuffer().reserveSlot(); } - LL_FORCE_INLINE ACCUMULATOR& getAccumulator() + LL_FORCE_INLINE ACCUMULATOR& getPrimaryAccumulator() { return AccumulatorBuffer::getPrimaryStorage()[mAccumulatorIndex]; } - private: + ACCUMULATOR& getAccumulator(AccumulatorBuffer& buffer) { return buffer[mAccumulatorIndex]; } + + protected: std::string mName; size_t mAccumulatorIndex; }; template - class StatAccumulator + class LL_COMMON_API StatAccumulator { public: StatAccumulator() @@ -217,6 +223,11 @@ namespace LLTrace mMax = 0; } + T getSum() { return mSum; } + T getMin() { return mMin; } + T getMax() { return mMax; } + T getMean() { return mSum / (T)mNumSamples; } + private: T mSum, mMin, @@ -226,20 +237,23 @@ namespace LLTrace }; template - class Stat : public Trace > + class LL_COMMON_API Stat + : public TraceType >, + public LLInstanceTracker, std::string> { public: Stat(const std::string& name) - : Trace(name) + : TraceType(name), + LLInstanceTracker(name) {} void sample(T value) { - getAccumulator().sample(value); + getPrimaryAccumulator().sample(value); } }; - struct TimerAccumulator + struct LL_COMMON_API TimerAccumulator { U32 mTotalTimeCounter, mChildTimeCounter, @@ -267,11 +281,11 @@ namespace LLTrace }; - class BlockTimer : public Trace + class LL_COMMON_API BlockTimer : public TraceType { public: BlockTimer(const char* name) - : Trace(name) + : TraceType(name) {} struct Recorder @@ -287,7 +301,7 @@ namespace LLTrace : mLastRecorder(sCurRecorder) { mStartTime = getCPUClockCount32(); - TimerAccumulator* accumulator = &block_timer.getAccumulator(); // get per-thread accumulator + TimerAccumulator* accumulator = &block_timer.getPrimaryAccumulator(); // get per-thread accumulator accumulator->mActiveCount++; accumulator->mCalls++; accumulator->mMoveUpTree |= (accumulator->mParent->mActiveCount == 0); @@ -353,44 +367,7 @@ namespace LLTrace static Recorder::StackEntry sCurRecorder; }; - class Sampler - { - public: - ~Sampler(); - - void makePrimary(); - - void start(); - void stop(); - void resume(); - - void mergeFrom(const Sampler* other); - - void reset(); - - bool isStarted() { return mIsStarted; } - - private: - friend class ThreadTrace; - Sampler(class ThreadTrace* thread_trace); - - // no copy - Sampler(const Sampler& other) {} - // returns data for current thread - class ThreadTrace* getThreadTrace(); - - AccumulatorBuffer > mF32Stats; - AccumulatorBuffer > mS32Stats; - - AccumulatorBuffer mStackTimers; - - bool mIsStarted; - LLTimer mSamplingTimer; - F64 mElapsedSeconds; - ThreadTrace* mThreadTrace; - }; - - class ThreadTrace + class LL_COMMON_API ThreadTrace { public: ThreadTrace(); @@ -406,13 +383,13 @@ namespace LLTrace virtual void pushToMaster() = 0; - Sampler* getPrimarySampler() { return mPrimarySampler; } + Sampler* getPrimarySampler(); protected: Sampler* mPrimarySampler; std::list mActiveSamplers; }; - class MasterThreadTrace : public ThreadTrace + class LL_COMMON_API MasterThreadTrace : public ThreadTrace { public: MasterThreadTrace(); @@ -433,14 +410,17 @@ namespace LLTrace ~SlaveThreadTraceProxy(); class SlaveThreadTrace* mSlaveTrace; Sampler* mSamplerStorage; + private: + //no need to copy these and then have to duplicate the storage + SlaveThreadTraceProxy(const SlaveThreadTraceProxy& other) {} }; - typedef std::list slave_thread_trace_list_t; + typedef std::list slave_thread_trace_list_t; slave_thread_trace_list_t mSlaveThreadTraces; LLMutex mSlaveListMutex; }; - class SlaveThreadTrace : public ThreadTrace + class LL_COMMON_API SlaveThreadTrace : public ThreadTrace { public: SlaveThreadTrace(); @@ -457,31 +437,12 @@ namespace LLTrace { public: explicit - SharedData(Sampler* sampler) - : mSampler(sampler) - { - } + SharedData(Sampler* sampler); - ~SharedData() - { - delete mSampler; - } + ~SharedData(); - void copyFrom(Sampler* source) - { - LLMutexLock lock(&mSamplerMutex); - { - mSampler->mergeFrom(source); - } - } - - void copyTo(Sampler* sink) - { - LLMutexLock lock(&mSamplerMutex); - { - sink->mergeFrom(mSampler); - } - } + void copyFrom(Sampler* source); + void copyTo(Sampler* sink); private: // add a cache line's worth of unused space to avoid any potential of false sharing LLMutex mSamplerMutex; @@ -489,14 +450,6 @@ namespace LLTrace }; SharedData mSharedData; }; - - class TimeInterval - { - public: - void start() {} - void stop() {} - void resume() {} - }; } #endif // LL_LLTRACE_H -- cgit v1.2.3 From 14b1b0b2bb6bac5bc688cc4d14c33f1b680dd3b4 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 1 Oct 2012 19:39:04 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages cleaned up API samplers are now value types with copy-on-write buffers under the hood removed coupling with LLThread --- indra/llcommon/lltrace.h | 180 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 143 insertions(+), 37 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index c6f920b5e4..5ec1c821c3 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -33,6 +33,8 @@ #include "llmutex.h" #include "llmemory.h" #include "lltimer.h" +#include "llrefcount.h" +#include "lltracesampler.h" #include @@ -48,11 +50,13 @@ namespace LLTrace void init(); void cleanup(); + LLThreadLocalPointer& get_thread_trace(); + class LL_COMMON_API MasterThreadTrace& getMasterThreadTrace(); // one per thread per type template - class LL_COMMON_API AccumulatorBuffer + class LL_COMMON_API AccumulatorBuffer : public LLRefCount { static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64; private: @@ -88,13 +92,23 @@ namespace LLTrace return mStorage[index]; } - void mergeFrom(const AccumulatorBuffer& other) + void mergeSamples(const AccumulatorBuffer& other) { llassert(mNextStorageSlot == other.mNextStorageSlot); for (size_t i = 0; i < mNextStorageSlot; i++) { - mStorage[i].mergeFrom(other.mStorage[i]); + mStorage[i].mergeSamples(other.mStorage[i]); + } + } + + void mergeDeltas(const AccumulatorBuffer& start, const AccumulatorBuffer& finish) + { + llassert(mNextStorageSlot == start.mNextStorageSlot && mNextStorageSlot == finish.mNextStorageSlot); + + for (size_t i = 0; i < mNextStorageSlot; i++) + { + mStorage[i].mergeDeltas(start.mStorage[i], finish.mStorage[i]); } } @@ -119,6 +133,11 @@ namespace LLTrace sPrimaryStorage = mStorage; } + bool isPrimary() const + { + return sPrimaryStorage == mStorage; + } + LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage() { return sPrimaryStorage.get(); @@ -149,9 +168,9 @@ namespace LLTrace ACCUMULATOR* mStorage; size_t mStorageSize; size_t mNextStorageSlot; - static LLThreadLocalPtr sPrimaryStorage; + static LLThreadLocalPointer sPrimaryStorage; }; - template LLThreadLocalPtr AccumulatorBuffer::sPrimaryStorage; + template LLThreadLocalPointer AccumulatorBuffer::sPrimaryStorage; template class LL_COMMON_API TraceType @@ -168,7 +187,7 @@ namespace LLTrace return AccumulatorBuffer::getPrimaryStorage()[mAccumulatorIndex]; } - ACCUMULATOR& getAccumulator(AccumulatorBuffer& buffer) { return buffer[mAccumulatorIndex]; } + ACCUMULATOR& getAccumulator(AccumulatorBuffer* buffer) { return (*buffer)[mAccumulatorIndex]; } protected: std::string mName; @@ -177,10 +196,10 @@ namespace LLTrace template - class LL_COMMON_API StatAccumulator + class LL_COMMON_API MeasurementAccumulator { public: - StatAccumulator() + MeasurementAccumulator() : mSum(0), mMin(0), mMax(0), @@ -199,9 +218,12 @@ namespace LLTrace { mMax = value; } + F32 old_mean = mMean; + mMean += ((F32)value - old_mean) / (F32)mNumSamples; + mStandardDeviation += ((F32)value - old_mean) * ((F32)value - mMean); } - void mergeFrom(const StatAccumulator& other) + void mergeSamples(const MeasurementAccumulator& other) { mSum += other.mSum; if (other.mMin < mMin) @@ -213,6 +235,28 @@ namespace LLTrace mMax = other.mMax; } mNumSamples += other.mNumSamples; + F32 weight = (F32)mNumSamples / (F32)(mNumSamples + other.mNumSamples); + mMean = mMean * weight + other.mMean * (1.f - weight); + + F32 n_1 = (F32)mNumSamples, + n_2 = (F32)other.mNumSamples; + F32 m_1 = mMean, + m_2 = other.mMean; + F32 sd_1 = mStandardDeviation, + sd_2 = other.mStandardDeviation; + // 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 + F32 variance = ((((n_1 - 1.f) * sd_1 * sd_1) + + ((n_2 - 1.f) * sd_2 * sd_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)); + mStandardDeviation = sqrtf(variance); + } + + void mergeDeltas(const MeasurementAccumulator& start, const MeasurementAccumulator& finish) + { + llerrs << "Delta merge invalid for measurement accumulators" << llendl; } void reset() @@ -226,23 +270,68 @@ namespace LLTrace T getSum() { return mSum; } T getMin() { return mMin; } T getMax() { return mMax; } - T getMean() { return mSum / (T)mNumSamples; } + F32 getMean() { return mMean; } + F32 getStandardDeviation() { return mStandardDeviation; } private: T mSum, mMin, mMax; + F32 mMean, + mStandardDeviation; + + U32 mNumSamples; + }; + + template + class LL_COMMON_API RateAccumulator + { + public: + RateAccumulator() + : mSum(0), + mNumSamples(0) + {} + + LL_FORCE_INLINE void add(T value) + { + mNumSamples++; + mSum += value; + } + + void mergeSamples(const RateAccumulator& other) + { + mSum += other.mSum; + mNumSamples += other.mNumSamples; + } + + void mergeDeltas(const RateAccumulator& start, const RateAccumulator& finish) + { + mSum += finish.mSum - start.mSum; + mNumSamples += finish.mNumSamples - start.mNumSamples; + } + + void reset() + { + mNumSamples = 0; + mSum = 0; + } + + T getSum() { return mSum; } + + private: + T mSum; + U32 mNumSamples; }; template - class LL_COMMON_API Stat - : public TraceType >, - public LLInstanceTracker, std::string> + class LL_COMMON_API Measurement + : public TraceType >, + public LLInstanceTracker, std::string> { public: - Stat(const std::string& name) + Measurement(const std::string& name) : TraceType(name), LLInstanceTracker(name) {} @@ -253,11 +342,30 @@ namespace LLTrace } }; - struct LL_COMMON_API TimerAccumulator + template + class LL_COMMON_API Rate + : public TraceType >, + public LLInstanceTracker, std::string> { + public: + Rate(const std::string& name) + : TraceType(name), + LLInstanceTracker(name) + {} + + void add(T value) + { + getPrimaryAccumulator().add(value); + } + }; + + class LL_COMMON_API TimerAccumulator + { + public: U32 mTotalTimeCounter, mChildTimeCounter, mCalls; + TimerAccumulator* mParent; // info for caller timer TimerAccumulator* mLastCaller; // used to bootstrap tree construction const class BlockTimer* mTimer; // points to block timer associated with this storage @@ -265,13 +373,20 @@ namespace LLTrace bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame std::vector mChildren; // currently assumed child timers - void mergeFrom(const TimerAccumulator& other) + void mergeSamples(const TimerAccumulator& other) { mTotalTimeCounter += other.mTotalTimeCounter; mChildTimeCounter += other.mChildTimeCounter; mCalls += other.mCalls; } + void mergeDeltas(const TimerAccumulator& start, const TimerAccumulator& finish) + { + mTotalTimeCounter += finish.mTotalTimeCounter - start.mTotalTimeCounter; + mChildTimeCounter += finish.mChildTimeCounter - start.mChildTimeCounter; + mCalls += finish.mCalls - start.mCalls; + } + void reset() { mTotalTimeCounter = 0; @@ -377,15 +492,13 @@ namespace LLTrace void activate(Sampler* sampler); void deactivate(Sampler* sampler); - void flushPrimary(); - - Sampler* createSampler(); virtual void pushToMaster() = 0; Sampler* getPrimarySampler(); protected: - Sampler* mPrimarySampler; + Sampler mPrimarySampler; + Sampler mTotalSampler; std::list mActiveSamplers; }; @@ -402,14 +515,15 @@ namespace LLTrace // call this periodically to gather stats data from slave threads void pullFromSlaveThreads(); + LLMutex* getSlaveListMutex() { return &mSlaveListMutex; } + private: struct SlaveThreadTraceProxy { - SlaveThreadTraceProxy(class SlaveThreadTrace* trace, Sampler* storage); + SlaveThreadTraceProxy(class SlaveThreadTrace* trace); - ~SlaveThreadTraceProxy(); class SlaveThreadTrace* mSlaveTrace; - Sampler* mSamplerStorage; + Sampler mSamplerStorage; private: //no need to copy these and then have to duplicate the storage SlaveThreadTraceProxy(const SlaveThreadTraceProxy& other) {} @@ -431,24 +545,16 @@ namespace LLTrace MasterThreadTrace* mMaster; - // this data is accessed by other threads, so give it a 64 byte alignment - // to avoid false sharing on most x86 processors - LL_ALIGNED(64) class SharedData + class SharedData { public: - explicit - SharedData(Sampler* sampler); - - ~SharedData(); - - void copyFrom(Sampler* source); - void copyTo(Sampler* sink); + void copyFrom(const Sampler& source); + void copyTo(Sampler& sink); private: - // add a cache line's worth of unused space to avoid any potential of false sharing - LLMutex mSamplerMutex; - Sampler* mSampler; + LLMutex mSamplerMutex; + Sampler mSampler; }; - SharedData mSharedData; + SharedData mSharedData; }; } -- cgit v1.2.3 From dbe9742703cf14db85ec3d16c540efc68dce95a6 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 2 Oct 2012 15:37:16 -0700 Subject: SH-3404 create sampler class renamed LLTrace::ThreadTrace to LLTrace::ThreadRecorder renamed LLTrace::Sampler to LLTrace::Recording --- indra/llcommon/lltrace.h | 66 ++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 5ec1c821c3..c5356777ae 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -34,7 +34,7 @@ #include "llmemory.h" #include "lltimer.h" #include "llrefcount.h" -#include "lltracesampler.h" +#include "lltracerecording.h" #include @@ -45,14 +45,14 @@ namespace LLTrace { - class Sampler; + class Recording; void init(); void cleanup(); - LLThreadLocalPointer& get_thread_trace(); + LLThreadLocalPointer& get_thread_recorder(); - class LL_COMMON_API MasterThreadTrace& getMasterThreadTrace(); + class LL_COMMON_API MasterThreadRecorder& getMasterThreadRecorder(); // one per thread per type template @@ -482,33 +482,33 @@ namespace LLTrace static Recorder::StackEntry sCurRecorder; }; - class LL_COMMON_API ThreadTrace + class LL_COMMON_API ThreadRecorder { public: - ThreadTrace(); - ThreadTrace(const ThreadTrace& other); + ThreadRecorder(); + ThreadRecorder(const ThreadRecorder& other); - virtual ~ThreadTrace(); + virtual ~ThreadRecorder(); - void activate(Sampler* sampler); - void deactivate(Sampler* sampler); + void activate(Recording* recording); + void deactivate(Recording* recording); virtual void pushToMaster() = 0; - Sampler* getPrimarySampler(); + Recording* getPrimaryRecording(); protected: - Sampler mPrimarySampler; - Sampler mTotalSampler; - std::list mActiveSamplers; + Recording mPrimaryRecording; + Recording mFullRecording; + std::list mActiveRecordings; }; - class LL_COMMON_API MasterThreadTrace : public ThreadTrace + class LL_COMMON_API MasterThreadRecorder : public ThreadRecorder { public: - MasterThreadTrace(); + MasterThreadRecorder(); - void addSlaveThread(class SlaveThreadTrace* child); - void removeSlaveThread(class SlaveThreadTrace* child); + void addSlaveThread(class SlaveThreadRecorder* child); + void removeSlaveThread(class SlaveThreadRecorder* child); /*virtual */ void pushToMaster(); @@ -518,41 +518,41 @@ namespace LLTrace LLMutex* getSlaveListMutex() { return &mSlaveListMutex; } private: - struct SlaveThreadTraceProxy + struct SlaveThreadRecorderProxy { - SlaveThreadTraceProxy(class SlaveThreadTrace* trace); + SlaveThreadRecorderProxy(class SlaveThreadRecorder* recorder); - class SlaveThreadTrace* mSlaveTrace; - Sampler mSamplerStorage; + class SlaveThreadRecorder* mRecorder; + Recording mSlaveRecording; private: //no need to copy these and then have to duplicate the storage - SlaveThreadTraceProxy(const SlaveThreadTraceProxy& other) {} + SlaveThreadRecorderProxy(const SlaveThreadRecorderProxy& other) {} }; - typedef std::list slave_thread_trace_list_t; + typedef std::list slave_thread_recorder_list_t; - slave_thread_trace_list_t mSlaveThreadTraces; + slave_thread_recorder_list_t mSlaveThreadRecorders; LLMutex mSlaveListMutex; }; - class LL_COMMON_API SlaveThreadTrace : public ThreadTrace + class LL_COMMON_API SlaveThreadRecorder : public ThreadRecorder { public: - SlaveThreadTrace(); - ~SlaveThreadTrace(); + SlaveThreadRecorder(); + ~SlaveThreadRecorder(); // call this periodically to gather stats data for master thread to consume /*virtual*/ void pushToMaster(); - MasterThreadTrace* mMaster; + MasterThreadRecorder* mMaster; class SharedData { public: - void copyFrom(const Sampler& source); - void copyTo(Sampler& sink); + void copyFrom(const Recording& source); + void copyTo(Recording& sink); private: - LLMutex mSamplerMutex; - Sampler mSampler; + LLMutex mRecorderMutex; + Recording mRecorder; }; SharedData mSharedData; }; -- cgit v1.2.3 From 7196619b4a0823a332e10b7f98464a1649e0dfd2 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 2 Oct 2012 17:14:12 -0700 Subject: 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 --- indra/llcommon/lltrace.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index c5356777ae..39de79e4c1 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -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 mActiveRecordings; + std::list mActiveRecordings; }; class LL_COMMON_API MasterThreadRecorder : public ThreadRecorder -- cgit v1.2.3 From 8f5e83789254d19a1a31737b0d7515cd7e967b26 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 3 Oct 2012 19:32:59 -0700 Subject: SH-3405 WIP convert existing stats to lltrace system SH-3403 FIX implement unit conversion LLUnit implements unit tracking and conversion added support for LLUnit to LLTrace duplicated most llstats into LLTrace equivalents --- indra/llcommon/lltrace.h | 62 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 7 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 39de79e4c1..6a889f74df 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -35,6 +35,7 @@ #include "lltimer.h" #include "llrefcount.h" #include "lltracerecording.h" +#include "llunit.h" #include @@ -42,11 +43,8 @@ #define TOKEN_PASTE(x, y) TOKEN_PASTE_ACTUAL(x, y) #define RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder TOKEN_PASTE(block_time_recorder, __COUNTER__)(block_timer); - namespace LLTrace { - class Recording; - void init(); void cleanup(); @@ -325,10 +323,10 @@ namespace LLTrace U32 mNumSamples; }; - template + template class LL_COMMON_API Measurement : public TraceType >, - public LLInstanceTracker, std::string> + public LLInstanceTracker, std::string> { public: Measurement(const std::string& name) @@ -343,13 +341,37 @@ namespace LLTrace }; template + class LL_COMMON_API Measurement + : public Measurement + { + public: + typedef Measurement base_measurement_t; + Measurement(const std::string& name) + : Measurement(name) + {} + + template + void sample(UNIT_T value) + { + base_measurement_t::sample(value.get()); + } + + template + typename T::value_t get() + { + UNIT_T value(*this); + return value.get(); + } + }; + + template class LL_COMMON_API Rate - : public TraceType >, + : public TraceType >, public LLInstanceTracker, std::string> { public: Rate(const std::string& name) - : TraceType(name), + : TraceType(name), LLInstanceTracker(name) {} @@ -359,6 +381,30 @@ namespace LLTrace } }; + template + class LL_COMMON_API Rate + : public Rate + { + public: + Rate(const std::string& name) + : Rate(name) + {} + + template + void add(UNIT_T value) + { + getPrimaryAccumulator().add(value.get()); + } + + template + typename T::value_t get() + { + UNIT_T value(*this); + return value.get(); + } + + }; + class LL_COMMON_API TimerAccumulator { public: @@ -482,6 +528,8 @@ namespace LLTrace static Recorder::StackEntry sCurRecorder; }; + class Recording; + class LL_COMMON_API ThreadRecorder { public: -- cgit v1.2.3 From 3960fdf9e01619ddfd7903bcdd8d894f432752d0 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 4 Oct 2012 23:11:57 -0700 Subject: SH-3275 WIP Update viewer metrics system to be more flexible moved threadrecorder classes into separate file added Count trace type, which tracks value increases and decreases and can report churn as well as overall growth rate --- indra/llcommon/lltrace.h | 143 ++++++++++++----------------------------------- 1 file changed, 35 insertions(+), 108 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 6a889f74df..d83ea77363 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -30,11 +30,10 @@ #include "stdtypes.h" #include "llpreprocessor.h" -#include "llmutex.h" #include "llmemory.h" -#include "lltimer.h" #include "llrefcount.h" #include "lltracerecording.h" +#include "lltracethreadrecorder.h" #include "llunit.h" #include @@ -171,7 +170,7 @@ namespace LLTrace template LLThreadLocalPointer AccumulatorBuffer::sPrimaryStorage; template - class LL_COMMON_API TraceType + class LL_COMMON_API TraceType { public: TraceType(const std::string& name) @@ -186,6 +185,7 @@ namespace LLTrace } ACCUMULATOR& getAccumulator(AccumulatorBuffer* buffer) { return (*buffer)[mAccumulatorIndex]; } + const ACCUMULATOR& getAccumulator(AccumulatorBuffer* buffer) const { return (*buffer)[mAccumulatorIndex]; } protected: std::string mName; @@ -265,11 +265,11 @@ namespace LLTrace mMax = 0; } - T getSum() { return mSum; } - T getMin() { return mMin; } - T getMax() { return mMax; } - F32 getMean() { return mMean; } - F32 getStandardDeviation() { return mStandardDeviation; } + T getSum() const { return mSum; } + T getMin() const { return mMin; } + T getMax() const { return mMax; } + F32 getMean() const { return mMean; } + F32 getStandardDeviation() const { return mStandardDeviation; } private: T mSum, @@ -315,7 +315,7 @@ namespace LLTrace mSum = 0; } - T getSum() { return mSum; } + T getSum() const { return mSum; } private: T mSum; @@ -355,13 +355,6 @@ namespace LLTrace { base_measurement_t::sample(value.get()); } - - template - typename T::value_t get() - { - UNIT_T value(*this); - return value.get(); - } }; template @@ -395,14 +388,35 @@ namespace LLTrace { getPrimaryAccumulator().add(value.get()); } + }; - template - typename T::value_t get() + template + class LL_COMMON_API Count + { + public: + Count(const std::string& name) + : mIncrease(name + "_increase"), + mDecrease(name + "_decrease"), + mTotal(name) + {} + + void count(T value) { - UNIT_T value(*this); - return value.get(); + if (value < 0) + { + mDecrease.add(value * -1); + } + else + { + mIncrease.add(value); + } + mTotal.add(value); } - + private: + friend class LLTrace::Recording; + Rate mIncrease; + Rate mDecrease; + Rate mTotal; }; class LL_COMMON_API TimerAccumulator @@ -527,93 +541,6 @@ namespace LLTrace static Recorder::StackEntry sCurRecorder; }; - - class Recording; - - class LL_COMMON_API ThreadRecorder - { - public: - ThreadRecorder(); - ThreadRecorder(const ThreadRecorder& other); - - virtual ~ThreadRecorder(); - - void activate(Recording* recording); - void deactivate(Recording* recording); - - virtual void pushToMaster() = 0; - - Recording* getPrimaryRecording(); - protected: - 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 mActiveRecordings; - }; - - class LL_COMMON_API MasterThreadRecorder : public ThreadRecorder - { - public: - MasterThreadRecorder(); - - void addSlaveThread(class SlaveThreadRecorder* child); - void removeSlaveThread(class SlaveThreadRecorder* child); - - /*virtual */ void pushToMaster(); - - // call this periodically to gather stats data from slave threads - void pullFromSlaveThreads(); - - LLMutex* getSlaveListMutex() { return &mSlaveListMutex; } - - private: - struct SlaveThreadRecorderProxy - { - SlaveThreadRecorderProxy(class SlaveThreadRecorder* recorder); - - class SlaveThreadRecorder* mRecorder; - Recording mSlaveRecording; - private: - //no need to copy these and then have to duplicate the storage - SlaveThreadRecorderProxy(const SlaveThreadRecorderProxy& other) {} - }; - typedef std::list slave_thread_recorder_list_t; - - slave_thread_recorder_list_t mSlaveThreadRecorders; - LLMutex mSlaveListMutex; - }; - - class LL_COMMON_API SlaveThreadRecorder : public ThreadRecorder - { - public: - SlaveThreadRecorder(); - ~SlaveThreadRecorder(); - - // call this periodically to gather stats data for master thread to consume - /*virtual*/ void pushToMaster(); - - MasterThreadRecorder* mMaster; - - class SharedData - { - public: - void copyFrom(const Recording& source); - void copyTo(Recording& sink); - private: - LLMutex mRecorderMutex; - Recording mRecorder; - }; - SharedData mSharedData; - }; } #endif // LL_LLTRACE_H -- cgit v1.2.3 From aff9654c1115b4a74fc3ee8f9ca2c2ffa07f8d73 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 9 Oct 2012 18:02:47 -0700 Subject: SH-3275 WIP Update viewer metrics system to be more flexible added PeriodicRecorder class for frame by frame stats accumulation --- indra/llcommon/lltrace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index d83ea77363..e655a3582e 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -353,7 +353,7 @@ namespace LLTrace template void sample(UNIT_T value) { - base_measurement_t::sample(value.get()); + base_measurement_t::sample(value.value()); } }; @@ -386,7 +386,7 @@ namespace LLTrace template void add(UNIT_T value) { - getPrimaryAccumulator().add(value.get()); + getPrimaryAccumulator().add(value.value()); } }; -- cgit v1.2.3 From 74ac0182ec8f7a0f6d0ea89f5814f0998ab90b62 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 10 Oct 2012 19:25:56 -0700 Subject: SH-3405 WIP convert existing stats to lltrace system fixed units conversion so that trace getters return convertable units removed circular dependencies from lltrace* converted more stats to lltrace --- indra/llcommon/lltrace.h | 88 ++++++++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 32 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index d83ea77363..539a37ce31 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -32,9 +32,9 @@ #include "llmemory.h" #include "llrefcount.h" -#include "lltracerecording.h" -#include "lltracethreadrecorder.h" +//#include "lltracethreadrecorder.h" #include "llunit.h" +#include "llapr.h" #include @@ -44,6 +44,8 @@ namespace LLTrace { + class Recording; + void init(); void cleanup(); @@ -89,23 +91,23 @@ namespace LLTrace return mStorage[index]; } - void mergeSamples(const AccumulatorBuffer& other) + void addSamples(const AccumulatorBuffer& other) { llassert(mNextStorageSlot == other.mNextStorageSlot); for (size_t i = 0; i < mNextStorageSlot; i++) { - mStorage[i].mergeSamples(other.mStorage[i]); + mStorage[i].addSamples(other.mStorage[i]); } } - void mergeDeltas(const AccumulatorBuffer& start, const AccumulatorBuffer& finish) + void addDeltas(const AccumulatorBuffer& start, const AccumulatorBuffer& finish) { llassert(mNextStorageSlot == start.mNextStorageSlot && mNextStorageSlot == finish.mNextStorageSlot); for (size_t i = 0; i < mNextStorageSlot; i++) { - mStorage[i].mergeDeltas(start.mStorage[i], finish.mStorage[i]); + mStorage[i].addDeltas(start.mStorage[i], finish.mStorage[i]); } } @@ -173,8 +175,9 @@ namespace LLTrace class LL_COMMON_API TraceType { public: - TraceType(const std::string& name) - : mName(name) + TraceType(const char* name, const char* description = NULL) + : mName(name), + mDescription(description ? description : "") { mAccumulatorIndex = AccumulatorBuffer::getDefaultBuffer().reserveSlot(); } @@ -189,6 +192,7 @@ namespace LLTrace protected: std::string mName; + std::string mDescription; size_t mAccumulatorIndex; }; @@ -201,6 +205,8 @@ namespace LLTrace : mSum(0), mMin(0), mMax(0), + mMean(0), + mVarianceSum(0), mNumSamples(0) {} @@ -218,10 +224,11 @@ namespace LLTrace } F32 old_mean = mMean; mMean += ((F32)value - old_mean) / (F32)mNumSamples; - mStandardDeviation += ((F32)value - old_mean) * ((F32)value - mMean); + mVarianceSum += ((F32)value - old_mean) * ((F32)value - mMean); + mLastValue = value; } - void mergeSamples(const MeasurementAccumulator& other) + void addSamples(const MeasurementAccumulator& other) { mSum += other.mSum; if (other.mMin < mMin) @@ -240,19 +247,20 @@ namespace LLTrace n_2 = (F32)other.mNumSamples; F32 m_1 = mMean, m_2 = other.mMean; - F32 sd_1 = mStandardDeviation, - sd_2 = other.mStandardDeviation; + F32 sd_1 = getStandardDeviation(), + sd_2 = other.getStandardDeviation(); // 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 - F32 variance = ((((n_1 - 1.f) * sd_1 * sd_1) - + ((n_2 - 1.f) * sd_2 * sd_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)); - mStandardDeviation = sqrtf(variance); + mVarianceSum = (F32)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)) + * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2)))) + / (n_1 + n_2 - 1.f)); + mLastValue = other.mLastValue; } - void mergeDeltas(const MeasurementAccumulator& start, const MeasurementAccumulator& finish) + void addDeltas(const MeasurementAccumulator& start, const MeasurementAccumulator& finish) { llerrs << "Delta merge invalid for measurement accumulators" << llendl; } @@ -268,16 +276,18 @@ namespace LLTrace T getSum() const { return mSum; } T getMin() const { return mMin; } T getMax() const { return mMax; } + T getLastValue() const { return mLastValue; } F32 getMean() const { return mMean; } - F32 getStandardDeviation() const { return mStandardDeviation; } + F32 getStandardDeviation() const { return sqrtf(mVarianceSum / mNumSamples); } private: T mSum, mMin, - mMax; + mMax, + mLastValue; F32 mMean, - mStandardDeviation; + mVarianceSum; U32 mNumSamples; }; @@ -297,13 +307,13 @@ namespace LLTrace mSum += value; } - void mergeSamples(const RateAccumulator& other) + void addSamples(const RateAccumulator& other) { mSum += other.mSum; mNumSamples += other.mNumSamples; } - void mergeDeltas(const RateAccumulator& start, const RateAccumulator& finish) + void addDeltas(const RateAccumulator& start, const RateAccumulator& finish) { mSum += finish.mSum - start.mSum; mNumSamples += finish.mNumSamples - start.mNumSamples; @@ -329,7 +339,10 @@ namespace LLTrace public LLInstanceTracker, std::string> { public: - Measurement(const std::string& name) + typedef T storage_t; + typedef T base_unit_t; + + Measurement(const char* name, const char* description = NULL) : TraceType(name), LLInstanceTracker(name) {} @@ -345,8 +358,11 @@ namespace LLTrace : public Measurement { public: + typedef typename T::storage_t storage_t; + typedef typename T::base_unit_t base_unit_t; + typedef Measurement base_measurement_t; - Measurement(const std::string& name) + Measurement(const char* name, const char* description = NULL) : Measurement(name) {} @@ -363,7 +379,10 @@ namespace LLTrace public LLInstanceTracker, std::string> { public: - Rate(const std::string& name) + typedef T storage_t; + typedef T base_unit_t; + + Rate(const char* name, const char* description = NULL) : TraceType(name), LLInstanceTracker(name) {} @@ -379,7 +398,10 @@ namespace LLTrace : public Rate { public: - Rate(const std::string& name) + typedef typename T::storage_t storage_t; + typedef typename T::base_unit_t base_unit_t; + + Rate(const char* name, const char* description = NULL) : Rate(name) {} @@ -394,7 +416,9 @@ namespace LLTrace class LL_COMMON_API Count { public: - Count(const std::string& name) + typedef typename Rate::base_unit_t base_unit_t; + + Count(const char* name) : mIncrease(name + "_increase"), mDecrease(name + "_decrease"), mTotal(name) @@ -413,7 +437,7 @@ namespace LLTrace mTotal.add(value); } private: - friend class LLTrace::Recording; + friend LLTrace::Recording; Rate mIncrease; Rate mDecrease; Rate mTotal; @@ -433,14 +457,14 @@ namespace LLTrace bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame std::vector mChildren; // currently assumed child timers - void mergeSamples(const TimerAccumulator& other) + void addSamples(const TimerAccumulator& other) { mTotalTimeCounter += other.mTotalTimeCounter; mChildTimeCounter += other.mChildTimeCounter; mCalls += other.mCalls; } - void mergeDeltas(const TimerAccumulator& start, const TimerAccumulator& finish) + void addDeltas(const TimerAccumulator& start, const TimerAccumulator& finish) { mTotalTimeCounter += finish.mTotalTimeCounter - start.mTotalTimeCounter; mChildTimeCounter += finish.mChildTimeCounter - start.mChildTimeCounter; -- cgit v1.2.3 From 0f58ca02cdec62711eadb82ba28fcff08faef2ee Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 12 Oct 2012 00:20:19 -0700 Subject: SH-3275 WIP Update viewer metrics system to be more flexible cleaned up accumulator merging logic introduced frame recording to LLTrace directly instead of going through LLViewerStats moved consumer code over to frame recording instead of whatever the current active recording was --- indra/llcommon/lltrace.h | 49 +++++++++++++++++------------------------------- 1 file changed, 17 insertions(+), 32 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index a6334e176b..0c618a2f4b 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -101,16 +101,6 @@ namespace LLTrace } } - void addDeltas(const AccumulatorBuffer& start, const AccumulatorBuffer& finish) - { - llassert(mNextStorageSlot == start.mNextStorageSlot && mNextStorageSlot == finish.mNextStorageSlot); - - for (size_t i = 0; i < mNextStorageSlot; i++) - { - mStorage[i].addDeltas(start.mStorage[i], finish.mStorage[i]); - } - } - void copyFrom(const AccumulatorBuffer& other) { for (size_t i = 0; i < mNextStorageSlot; i++) @@ -203,11 +193,12 @@ namespace LLTrace public: MeasurementAccumulator() : mSum(0), - mMin(0), - mMax(0), + mMin(std::numeric_limits::max()), + mMax(std::numeric_limits::min()), mMean(0), mVarianceSum(0), - mNumSamples(0) + mNumSamples(0), + mLastValue(0) {} LL_FORCE_INLINE void sample(T value) @@ -251,20 +242,27 @@ namespace LLTrace sd_2 = other.getStandardDeviation(); // 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 - mVarianceSum = (F32)mNumSamples + if (n_1 == 0) + { + mVarianceSum = other.mVarianceSum; + } + else if (n_2 == 0) + { + // don't touch variance + // mVarianceSum = mVarianceSum; + } + else + { + mVarianceSum = (F32)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)) * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2)))) / (n_1 + n_2 - 1.f)); + } mLastValue = other.mLastValue; } - void addDeltas(const MeasurementAccumulator& start, const MeasurementAccumulator& finish) - { - llerrs << "Delta merge invalid for measurement accumulators" << llendl; - } - void reset() { mNumSamples = 0; @@ -313,12 +311,6 @@ namespace LLTrace mNumSamples += other.mNumSamples; } - void addDeltas(const RateAccumulator& start, const RateAccumulator& finish) - { - mSum += finish.mSum - start.mSum; - mNumSamples += finish.mNumSamples - start.mNumSamples; - } - void reset() { mNumSamples = 0; @@ -464,13 +456,6 @@ namespace LLTrace mCalls += other.mCalls; } - void addDeltas(const TimerAccumulator& start, const TimerAccumulator& finish) - { - mTotalTimeCounter += finish.mTotalTimeCounter - start.mTotalTimeCounter; - mChildTimeCounter += finish.mChildTimeCounter - start.mChildTimeCounter; - mCalls += finish.mCalls - start.mCalls; - } - void reset() { mTotalTimeCounter = 0; -- cgit v1.2.3 From 041dfccd1ea5b59c1b3c4e37e9a5495cad342c8f Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 12 Oct 2012 20:17:52 -0700 Subject: SH-3405 WIP convert existing stats to lltrace system default to double precision now fixed unit conversion logic for LLUnit renamed LLTrace::Rate to LLTrace::Count and got rid of the old count as it was confusing some const correctness changes --- indra/llcommon/lltrace.h | 93 ++++++++++++++++++------------------------------ 1 file changed, 34 insertions(+), 59 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 0c618a2f4b..221c226ad1 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -91,6 +91,11 @@ namespace LLTrace return mStorage[index]; } + LL_FORCE_INLINE const ACCUMULATOR& operator[](size_t index) const + { + return mStorage[index]; + } + void addSamples(const AccumulatorBuffer& other) { llassert(mNextStorageSlot == other.mNextStorageSlot); @@ -178,7 +183,7 @@ namespace LLTrace } ACCUMULATOR& getAccumulator(AccumulatorBuffer* buffer) { return (*buffer)[mAccumulatorIndex]; } - const ACCUMULATOR& getAccumulator(AccumulatorBuffer* buffer) const { return (*buffer)[mAccumulatorIndex]; } + const ACCUMULATOR& getAccumulator(const AccumulatorBuffer* buffer) const { return (*buffer)[mAccumulatorIndex]; } protected: std::string mName; @@ -213,9 +218,9 @@ namespace LLTrace { mMax = value; } - F32 old_mean = mMean; - mMean += ((F32)value - old_mean) / (F32)mNumSamples; - mVarianceSum += ((F32)value - old_mean) * ((F32)value - mMean); + F64 old_mean = mMean; + mMean += ((F64)value - old_mean) / (F64)mNumSamples; + mVarianceSum += ((F64)value - old_mean) * ((F64)value - mMean); mLastValue = value; } @@ -231,14 +236,14 @@ namespace LLTrace mMax = other.mMax; } mNumSamples += other.mNumSamples; - F32 weight = (F32)mNumSamples / (F32)(mNumSamples + other.mNumSamples); + F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples); mMean = mMean * weight + other.mMean * (1.f - weight); - F32 n_1 = (F32)mNumSamples, - n_2 = (F32)other.mNumSamples; - F32 m_1 = mMean, + F64 n_1 = (F64)mNumSamples, + n_2 = (F64)other.mNumSamples; + F64 m_1 = mMean, m_2 = other.mMean; - F32 sd_1 = getStandardDeviation(), + F64 sd_1 = getStandardDeviation(), sd_2 = other.getStandardDeviation(); // 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 @@ -275,8 +280,8 @@ namespace LLTrace T getMin() const { return mMin; } T getMax() const { return mMax; } T getLastValue() const { return mLastValue; } - F32 getMean() const { return mMean; } - F32 getStandardDeviation() const { return sqrtf(mVarianceSum / mNumSamples); } + F64 getMean() const { return mMean; } + F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mNumSamples); } private: T mSum, @@ -284,17 +289,17 @@ namespace LLTrace mMax, mLastValue; - F32 mMean, + F64 mMean, mVarianceSum; U32 mNumSamples; }; template - class LL_COMMON_API RateAccumulator + class LL_COMMON_API CountAccumulator { public: - RateAccumulator() + CountAccumulator() : mSum(0), mNumSamples(0) {} @@ -305,7 +310,7 @@ namespace LLTrace mSum += value; } - void addSamples(const RateAccumulator& other) + void addSamples(const CountAccumulator& other) { mSum += other.mSum; mNumSamples += other.mNumSamples; @@ -325,7 +330,7 @@ namespace LLTrace U32 mNumSamples; }; - template + template class LL_COMMON_API Measurement : public TraceType >, public LLInstanceTracker, std::string> @@ -352,8 +357,8 @@ namespace LLTrace public: typedef typename T::storage_t storage_t; typedef typename T::base_unit_t base_unit_t; - typedef Measurement base_measurement_t; + Measurement(const char* name, const char* description = NULL) : Measurement(name) {} @@ -361,20 +366,20 @@ namespace LLTrace template void sample(UNIT_T value) { - base_measurement_t::sample(value.value()); + base_measurement_t::sample(((T)value).value()); } }; - template - class LL_COMMON_API Rate - : public TraceType >, - public LLInstanceTracker, std::string> + template + class LL_COMMON_API Count + : public TraceType >, + public LLInstanceTracker, std::string> { public: typedef T storage_t; typedef T base_unit_t; - Rate(const char* name, const char* description = NULL) + Count(const char* name, const char* description = NULL) : TraceType(name), LLInstanceTracker(name) {} @@ -386,53 +391,23 @@ namespace LLTrace }; template - class LL_COMMON_API Rate - : public Rate + class LL_COMMON_API Count + : public Count { public: typedef typename T::storage_t storage_t; typedef typename T::base_unit_t base_unit_t; + typedef Count base_count_t; - Rate(const char* name, const char* description = NULL) - : Rate(name) + Count(const char* name, const char* description = NULL) + : Count(name) {} template void add(UNIT_T value) { - getPrimaryAccumulator().add(value.value()); - } - }; - - template - class LL_COMMON_API Count - { - public: - typedef typename Rate::base_unit_t base_unit_t; - - Count(const char* name) - : mIncrease(name + "_increase"), - mDecrease(name + "_decrease"), - mTotal(name) - {} - - void count(T value) - { - if (value < 0) - { - mDecrease.add(value * -1); - } - else - { - mIncrease.add(value); - } - mTotal.add(value); + base_count_t::add(((T)value).value()); } - private: - friend LLTrace::Recording; - Rate mIncrease; - Rate mDecrease; - Rate mTotal; }; class LL_COMMON_API TimerAccumulator -- cgit v1.2.3 From 8d2f7a526545a10cd3669bf837a0b6f02cf5fe71 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 15 Oct 2012 19:43:35 -0700 Subject: SH-3405 WIP convert existing stats to lltrace system converted all remaining LLViewerStats to lltrace --- indra/llcommon/lltrace.h | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 221c226ad1..3e19c83bd7 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -282,6 +282,7 @@ namespace LLTrace T getLastValue() const { return mLastValue; } F64 getMean() const { return mMean; } F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mNumSamples); } + U32 getSampleCount() const { return mNumSamples; } private: T mSum, -- cgit v1.2.3 From e6ca5471a2a816a24888ae1b38332531b22b7254 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 17 Oct 2012 00:06:22 -0700 Subject: SH-3275 Update viewer metrics system to be more flexible put template parameter back in LLUnit units added free function operators for mathematical manipulation of unit values converted texture memory tracking to units --- indra/llcommon/lltrace.h | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 3e19c83bd7..1c6726605a 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -46,6 +46,30 @@ namespace LLTrace { class Recording; + typedef LLUnit::Bytes Bytes; + typedef LLUnit::Kilobytes Kilobytes; + typedef LLUnit::Megabytes Megabytes; + typedef LLUnit::Gigabytes Gigabytes; + typedef LLUnit::Bits Bits; + typedef LLUnit::Kilobits Kilobits; + typedef LLUnit::Megabits Megabits; + typedef LLUnit::Gigabits Gigabits; + + typedef LLUnit::Seconds Seconds; + typedef LLUnit::Milliseconds Milliseconds; + typedef LLUnit::Minutes Minutes; + typedef LLUnit::Hours Hours; + typedef LLUnit::Days Days; + typedef LLUnit::Weeks Weeks; + typedef LLUnit::Milliseconds Milliseconds; + typedef LLUnit::Microseconds Microseconds; + typedef LLUnit::Nanoseconds Nanoseconds; + + typedef LLUnit::Meters Meters; + typedef LLUnit::Kilometers Kilometers; + typedef LLUnit::Centimeters Centimeters; + typedef LLUnit::Millimeters Millimeters; + void init(); void cleanup(); @@ -353,15 +377,15 @@ namespace LLTrace template class LL_COMMON_API Measurement - : public Measurement + : public Measurement { public: typedef typename T::storage_t storage_t; typedef typename T::base_unit_t base_unit_t; - typedef Measurement base_measurement_t; + typedef Measurement base_measurement_t; Measurement(const char* name, const char* description = NULL) - : Measurement(name) + : Measurement(name, description) {} template @@ -393,15 +417,15 @@ namespace LLTrace template class LL_COMMON_API Count - : public Count + : public Count { public: typedef typename T::storage_t storage_t; typedef typename T::base_unit_t base_unit_t; - typedef Count base_count_t; + typedef Count base_count_t; Count(const char* name, const char* description = NULL) - : Count(name) + : Count(name) {} template -- cgit v1.2.3 From a52d203a4f1d2988e8ffba16258f3f132f22f56d Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 17 Oct 2012 20:00:07 -0700 Subject: SH-3405 WIP convert existing stats to lltrace system started conversion of llviewerassetstats removed old, dead LLViewerStats code made units tracing require units declaration clean up of units handling --- indra/llcommon/lltrace.h | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 1c6726605a..2a479b31d7 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -192,10 +192,12 @@ namespace LLTrace template class LL_COMMON_API TraceType + : public LLInstanceTracker, std::string> { public: TraceType(const char* name, const char* description = NULL) - : mName(name), + : LLInstanceTracker(name), + mName(name), mDescription(description ? description : "") { mAccumulatorIndex = AccumulatorBuffer::getDefaultBuffer().reserveSlot(); @@ -355,18 +357,17 @@ namespace LLTrace U32 mNumSamples; }; + typedef TraceType > measurement_common_t; + template class LL_COMMON_API Measurement - : public TraceType >, - public LLInstanceTracker, std::string> + : public TraceType > { public: typedef T storage_t; - typedef T base_unit_t; Measurement(const char* name, const char* description = NULL) - : TraceType(name), - LLInstanceTracker(name) + : TraceType(name, description) {} void sample(T value) @@ -376,37 +377,37 @@ namespace LLTrace }; template - class LL_COMMON_API Measurement - : public Measurement + class LL_COMMON_API Measurement + : public TraceType > { public: typedef typename T::storage_t storage_t; - typedef typename T::base_unit_t base_unit_t; typedef Measurement base_measurement_t; Measurement(const char* name, const char* description = NULL) - : Measurement(name, description) + : TraceType(name, description) {} template void sample(UNIT_T value) { - base_measurement_t::sample(((T)value).value()); + T converted_value; + converted_value.assignFrom(value); + getPrimaryAccumulator().sample(converted_value.value()); } }; + typedef TraceType > count_common_t; + template class LL_COMMON_API Count - : public TraceType >, - public LLInstanceTracker, std::string> + : public TraceType > { public: typedef T storage_t; - typedef T base_unit_t; Count(const char* name, const char* description = NULL) - : TraceType(name), - LLInstanceTracker(name) + : TraceType(name) {} void add(T value) @@ -416,22 +417,23 @@ namespace LLTrace }; template - class LL_COMMON_API Count - : public Count + class LL_COMMON_API Count + : public TraceType > { public: typedef typename T::storage_t storage_t; - typedef typename T::base_unit_t base_unit_t; typedef Count base_count_t; Count(const char* name, const char* description = NULL) - : Count(name) + : TraceType(name) {} template void add(UNIT_T value) { - base_count_t::add(((T)value).value()); + T converted_value; + converted_value.assignFrom(value); + getPrimaryAccumulator().add(converted_value.value()); } }; -- cgit v1.2.3 From 1fadd6138eebf980776f80b9642f4c19279fcadd Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 18 Oct 2012 17:32:44 -0700 Subject: SH-3405 WIP convert existing stats to lltrace system fixed trace recording on background threads hitting null pointer --- indra/llcommon/lltrace.h | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 2a479b31d7..2cdae4b0d2 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -167,15 +167,24 @@ namespace LLTrace size_t next_slot = mNextStorageSlot++; if (next_slot >= mStorageSize) { - size_t new_size = mStorageSize + (mStorageSize >> 2); - delete [] mStorage; - mStorage = new ACCUMULATOR[new_size]; - mStorageSize = new_size; + resize(mStorageSize + (mStorageSize >> 2)); } - llassert(next_slot < mStorageSize); + llassert(mStorage && next_slot < mStorageSize); return next_slot; } + void resize(size_t new_size) + { + ACCUMULATOR* old_storage = mStorage; + mStorage = new ACCUMULATOR[new_size]; + for (S32 i = 0; i < mStorageSize; i++) + { + mStorage[i] = old_storage[i]; + } + mStorageSize = new_size; + delete[] old_storage; + } + static AccumulatorBuffer& getDefaultBuffer() { static AccumulatorBuffer sBuffer(STATIC_ALLOC); -- cgit v1.2.3 From 819adb5eb4d7f982121f3dbd82750e05d26864d9 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 1 Nov 2012 00:26:44 -0700 Subject: SH-3405 FIX convert existing stats to lltrace system final removal of remaining LLStat code --- indra/llcommon/lltrace.h | 90 +++++++++++++++++++++++++++++++----------------- 1 file changed, 58 insertions(+), 32 deletions(-) (limited to 'indra/llcommon/lltrace.h') 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 + struct StorageType + { + typedef T type_t; + }; + + template + struct StorageType + { + typedef typename StorageType::type_t type_t; + }; + + template<> struct StorageType { typedef F64 type_t; }; + template<> struct StorageType { typedef S64 type_t; }; + template<> struct StorageType { typedef S64 type_t; }; + template<> struct StorageType { typedef S64 type_t; }; + template<> struct StorageType { typedef S64 type_t; }; + template<> struct StorageType { typedef S64 type_t; }; + template<> struct StorageType { typedef S64 type_t; }; + template class LL_COMMON_API MeasurementAccumulator { public: + typedef T value_t; + typedef MeasurementAccumulator self_t; + MeasurementAccumulator() : mSum(0), mMin(std::numeric_limits::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& 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 > measurement_common_t; + typedef TraceType > measurement_common_float_t; + typedef TraceType > measurement_common_int_t; template class LL_COMMON_API Measurement - : public TraceType > + : public TraceType::type_t> > { public: - typedef T storage_t; + typedef typename StorageType::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 class LL_COMMON_API Measurement - : public TraceType > + : public TraceType::type_t> > { public: - typedef typename T::storage_t storage_t; - typedef Measurement base_measurement_t; + typedef typename StorageType::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 > count_common_t; + typedef TraceType > count_common_float_t; + typedef TraceType > count_common_int_t; template class LL_COMMON_API Count - : public TraceType > + : public TraceType::type_t> > { public: - typedef T storage_t; + typedef typename StorageType::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 class LL_COMMON_API Count - : public TraceType > + : public TraceType::type_t> > { public: - typedef typename T::storage_t storage_t; - typedef Count base_count_t; + typedef typename StorageType::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()); } }; -- cgit v1.2.3 From 74fe126590fba03752d1d8d88dd3bb59c6900026 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 1 Nov 2012 17:52:11 -0700 Subject: SH-3405 FIX convert existing stats to lltrace system output of floater_stats is now identical to pre-lltrace system (with some tweaks) --- indra/llcommon/lltrace.h | 95 ++++++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 43 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 2823db5cbb..735c45754c 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -138,11 +138,11 @@ namespace LLTrace } } - void reset() + void reset(const AccumulatorBuffer* other = NULL) { for (size_t i = 0; i < mNextStorageSlot; i++) { - mStorage[i].reset(); + mStorage[i].reset(other ? &other->mStorage[i] : NULL); } } @@ -285,54 +285,60 @@ namespace LLTrace void addSamples(const self_t& other) { - mSum += other.mSum; - if (other.mMin < mMin) - { - mMin = other.mMin; - } - if (other.mMax > mMax) - { - mMax = other.mMax; - } - mNumSamples += other.mNumSamples; - F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples); - mMean = mMean * weight + other.mMean * (1.f - weight); - - F64 n_1 = (F64)mNumSamples, - n_2 = (F64)other.mNumSamples; - F64 m_1 = mMean, - m_2 = other.mMean; - F64 sd_1 = getStandardDeviation(), - sd_2 = other.getStandardDeviation(); - // 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 - if (n_1 == 0) + if (other.mNumSamples) { - mVarianceSum = other.mVarianceSum; + mSum += other.mSum; + if (other.mMin < mMin) + { + mMin = other.mMin; + } + if (other.mMax > mMax) + { + mMax = other.mMax; + } + F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples); + mNumSamples += other.mNumSamples; + mMean = mMean * weight + other.mMean * (1.f - weight); + + F64 n_1 = (F64)mNumSamples, + n_2 = (F64)other.mNumSamples; + F64 m_1 = mMean, + m_2 = other.mMean; + F64 sd_1 = getStandardDeviation(), + sd_2 = other.getStandardDeviation(); + // 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 + if (n_1 == 0) + { + mVarianceSum = other.mVarianceSum; + } + else if (n_2 == 0) + { + // don't touch variance + // mVarianceSum = mVarianceSum; + } + else + { + 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)) + * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2)))) + / (n_1 + n_2 - 1.f)); + } + mLastValue = other.mLastValue; } - else if (n_2 == 0) - { - // don't touch variance - // mVarianceSum = mVarianceSum; - } - else - { - 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)) - * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2)))) - / (n_1 + n_2 - 1.f)); - } - mLastValue = other.mLastValue; } - void reset() + void reset(const self_t* other) { mNumSamples = 0; mSum = 0; mMin = 0; mMax = 0; + mMean = 0; + mVarianceSum = 0; + mLastValue = other ? other->mLastValue : 0; } T getSum() const { return (T)mSum; } @@ -359,6 +365,7 @@ namespace LLTrace class LL_COMMON_API CountAccumulator { public: + typedef CountAccumulator self_t; typedef T value_t; CountAccumulator() @@ -378,7 +385,7 @@ namespace LLTrace mNumSamples += other.mNumSamples; } - void reset() + void reset(const self_t* other) { mNumSamples = 0; mSum = 0; @@ -475,6 +482,8 @@ namespace LLTrace class LL_COMMON_API TimerAccumulator { public: + typedef TimerAccumulator self_t; + U32 mTotalTimeCounter, mChildTimeCounter, mCalls; @@ -493,7 +502,7 @@ namespace LLTrace mCalls += other.mCalls; } - void reset() + void reset(const self_t* other) { mTotalTimeCounter = 0; mChildTimeCounter = 0; -- cgit v1.2.3 From 0007114cf5a60779319ab8cbd0a23a0d462b8010 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 5 Nov 2012 16:10:57 -0800 Subject: SH-3499 WIP Ensure asset stats output is correct fixed copy behavior of recordings and accumulator buffers --- indra/llcommon/lltrace.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 735c45754c..8ad391e6e5 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -38,9 +38,9 @@ #include -#define TOKEN_PASTE_ACTUAL(x, y) x##y -#define TOKEN_PASTE(x, y) TOKEN_PASTE_ACTUAL(x, y) -#define RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder TOKEN_PASTE(block_time_recorder, __COUNTER__)(block_timer); +#define LL_TOKEN_PASTE_ACTUAL(x, y) x##y +#define LL_TOKEN_PASTE(x, y) LL_TOKEN_PASTE_ACTUAL(x, y) +#define LL_RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder LL_TOKEN_PASTE(block_time_recorder, __COUNTER__)(block_timer); namespace LLTrace { @@ -93,13 +93,16 @@ namespace LLTrace public: - // copying an accumulator buffer does not copy the actual contents, but simply initializes the buffer size - // to be identical to the other buffer AccumulatorBuffer(const AccumulatorBuffer& other = getDefaultBuffer()) : mStorageSize(other.mStorageSize), mStorage(new ACCUMULATOR[other.mStorageSize]), mNextStorageSlot(other.mNextStorageSlot) - {} + { + for (S32 i = 0; i < mNextStorageSlot; i++) + { + mStorage[i] = other.mStorage[i]; + } + } ~AccumulatorBuffer() { -- cgit v1.2.3 From 860ff2f7e2a7fe932dfb7c148f0dbc0067018038 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 7 Nov 2012 00:38:21 -0800 Subject: SH-3499 WIP Ensure asset stats output is correct fixed trace data gathering and routing from background thread simplified slave->master thread communication (eliminated redundant recording and proxy object) improved performance of fast timer data gathering (slow iterators) --- indra/llcommon/lltrace.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 8ad391e6e5..e2530a8a24 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -220,8 +220,7 @@ namespace LLTrace return AccumulatorBuffer::getPrimaryStorage()[mAccumulatorIndex]; } - ACCUMULATOR& getAccumulator(AccumulatorBuffer* buffer) { return (*buffer)[mAccumulatorIndex]; } - const ACCUMULATOR& getAccumulator(const AccumulatorBuffer* buffer) const { return (*buffer)[mAccumulatorIndex]; } + size_t getIndex() const { return mAccumulatorIndex; } protected: std::string mName; @@ -396,6 +395,8 @@ namespace LLTrace T getSum() const { return (T)mSum; } + U32 getSampleCount() const { return mNumSamples; } + private: T mSum; -- cgit v1.2.3 From 0bb0bd514b235948c1a21c81ab0e8ab6223b1990 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 8 Nov 2012 23:42:18 -0800 Subject: SH-3499 WIP Ensure asset stats output is correct Finished making LLUnit implicitly convertible to/from scalar integer values cleaned up test code --- indra/llcommon/lltrace.h | 54 +++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 28 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index e2530a8a24..d289ea9a88 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -38,37 +38,35 @@ #include -#define LL_TOKEN_PASTE_ACTUAL(x, y) x##y -#define LL_TOKEN_PASTE(x, y) LL_TOKEN_PASTE_ACTUAL(x, y) -#define LL_RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder LL_TOKEN_PASTE(block_time_recorder, __COUNTER__)(block_timer); +#define LL_RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder LL_GLUE_TOKENS(block_time_recorder, __COUNTER__)(block_timer); namespace LLTrace { class Recording; - typedef LLUnit::Bytes Bytes; - typedef LLUnit::Kilobytes Kilobytes; - typedef LLUnit::Megabytes Megabytes; - typedef LLUnit::Gigabytes Gigabytes; - typedef LLUnit::Bits Bits; - typedef LLUnit::Kilobits Kilobits; - typedef LLUnit::Megabits Megabits; - typedef LLUnit::Gigabits Gigabits; - - typedef LLUnit::Seconds Seconds; - typedef LLUnit::Milliseconds Milliseconds; - typedef LLUnit::Minutes Minutes; - typedef LLUnit::Hours Hours; - typedef LLUnit::Days Days; - typedef LLUnit::Weeks Weeks; - typedef LLUnit::Milliseconds Milliseconds; - typedef LLUnit::Microseconds Microseconds; - typedef LLUnit::Nanoseconds Nanoseconds; - - typedef LLUnit::Meters Meters; - typedef LLUnit::Kilometers Kilometers; - typedef LLUnit::Centimeters Centimeters; - typedef LLUnit::Millimeters Millimeters; + typedef LLUnit Bytes; + typedef LLUnit Kilobytes; + typedef LLUnit Megabytes; + typedef LLUnit Gigabytes; + typedef LLUnit Bits; + typedef LLUnit Kilobits; + typedef LLUnit Megabits; + typedef LLUnit Gigabits; + + typedef LLUnit Seconds; + typedef LLUnit Milliseconds; + typedef LLUnit Minutes; + typedef LLUnit Hours; + typedef LLUnit Days; + typedef LLUnit Weeks; + typedef LLUnit Milliseconds; + typedef LLUnit Microseconds; + typedef LLUnit Nanoseconds; + + typedef LLUnit Meters; + typedef LLUnit Kilometers; + typedef LLUnit Centimeters; + typedef LLUnit Millimeters; void init(); void cleanup(); @@ -438,7 +436,7 @@ namespace LLTrace void sample(UNIT_T value) { T converted_value; - converted_value.assignFrom(value); + converted_value = value; getPrimaryAccumulator().sample((storage_t)converted_value.value()); } }; @@ -478,7 +476,7 @@ namespace LLTrace void add(UNIT_T value) { T converted_value; - converted_value.assignFrom(value); + converted_value = value; getPrimaryAccumulator().add((storage_t)converted_value.value()); } }; -- cgit v1.2.3 From a3e3e8b4ccd96e98da73acf1c584bbfa5a8b2b56 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 12 Nov 2012 19:08:14 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system simplified llfasttimer code down to 2 classes llunit unit conversion now done in floating point or 64 bit integer precision, depending on source type --- indra/llcommon/lltrace.h | 39 ++++++++------------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index d289ea9a88..549e407822 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -57,8 +57,6 @@ namespace LLTrace typedef LLUnit Milliseconds; typedef LLUnit Minutes; typedef LLUnit Hours; - typedef LLUnit Days; - typedef LLUnit Weeks; typedef LLUnit Milliseconds; typedef LLUnit Microseconds; typedef LLUnit Nanoseconds; @@ -226,27 +224,6 @@ namespace LLTrace size_t mAccumulatorIndex; }; - - template - struct StorageType - { - typedef T type_t; - }; - - template - struct StorageType - { - typedef typename StorageType::type_t type_t; - }; - - template<> struct StorageType { typedef F64 type_t; }; - template<> struct StorageType { typedef S64 type_t; }; - template<> struct StorageType { typedef S64 type_t; }; - template<> struct StorageType { typedef S64 type_t; }; - template<> struct StorageType { typedef S64 type_t; }; - template<> struct StorageType { typedef S64 type_t; }; - template<> struct StorageType { typedef S64 type_t; }; - template class LL_COMMON_API MeasurementAccumulator { @@ -406,10 +383,10 @@ namespace LLTrace template class LL_COMMON_API Measurement - : public TraceType::type_t> > + : public TraceType::type_t> > { public: - typedef typename StorageType::type_t storage_t; + typedef typename LLUnits::HighestPrecisionType::type_t storage_t; Measurement(const char* name, const char* description = NULL) : TraceType(name, description) @@ -423,10 +400,10 @@ namespace LLTrace template class LL_COMMON_API Measurement - : public TraceType::type_t> > + : public TraceType::type_t> > { public: - typedef typename StorageType::type_t storage_t; + typedef typename LLUnits::HighestPrecisionType::type_t storage_t; Measurement(const char* name, const char* description = NULL) : TraceType(name, description) @@ -446,10 +423,10 @@ namespace LLTrace template class LL_COMMON_API Count - : public TraceType::type_t> > + : public TraceType::type_t> > { public: - typedef typename StorageType::type_t storage_t; + typedef typename LLUnits::HighestPrecisionType::type_t storage_t; Count(const char* name, const char* description = NULL) : TraceType(name) @@ -463,10 +440,10 @@ namespace LLTrace template class LL_COMMON_API Count - : public TraceType::type_t> > + : public TraceType::type_t> > { public: - typedef typename StorageType::type_t storage_t; + typedef typename LLUnits::HighestPrecisionType::type_t storage_t; Count(const char* name, const char* description = NULL) : TraceType(name) -- cgit v1.2.3 From 67ec47e6da389661934ed2ddfa55ca58455fa7e5 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 13 Nov 2012 17:10:10 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system moving fast timers into lltrace namespace and accumulation system --- indra/llcommon/lltrace.h | 194 +++++------------------------------------------ 1 file changed, 18 insertions(+), 176 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 549e407822..fb9dca5e84 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -32,7 +32,6 @@ #include "llmemory.h" #include "llrefcount.h" -//#include "lltracethreadrecorder.h" #include "llunit.h" #include "llapr.h" @@ -61,8 +60,8 @@ namespace LLTrace typedef LLUnit Microseconds; typedef LLUnit Nanoseconds; - typedef LLUnit Meters; - typedef LLUnit Kilometers; + typedef LLUnit Meters; + typedef LLUnit Kilometers; typedef LLUnit Centimeters; typedef LLUnit Millimeters; @@ -71,11 +70,11 @@ namespace LLTrace LLThreadLocalPointer& get_thread_recorder(); - class LL_COMMON_API MasterThreadRecorder& getMasterThreadRecorder(); + class MasterThreadRecorder& getMasterThreadRecorder(); // one per thread per type template - class LL_COMMON_API AccumulatorBuffer : public LLRefCount + class AccumulatorBuffer : public LLRefCount { static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64; private: @@ -199,7 +198,7 @@ namespace LLTrace template LLThreadLocalPointer AccumulatorBuffer::sPrimaryStorage; template - class LL_COMMON_API TraceType + class TraceType : public LLInstanceTracker, std::string> { public: @@ -218,6 +217,9 @@ namespace LLTrace size_t getIndex() const { return mAccumulatorIndex; } + std::string& getName() { return mName; } + const std::string& getName() const { return mName; } + protected: std::string mName; std::string mDescription; @@ -225,7 +227,7 @@ namespace LLTrace }; template - class LL_COMMON_API MeasurementAccumulator + class MeasurementAccumulator { public: typedef T value_t; @@ -339,7 +341,7 @@ namespace LLTrace }; template - class LL_COMMON_API CountAccumulator + class CountAccumulator { public: typedef CountAccumulator self_t; @@ -378,11 +380,8 @@ namespace LLTrace U32 mNumSamples; }; - typedef TraceType > measurement_common_float_t; - typedef TraceType > measurement_common_int_t; - - template - class LL_COMMON_API Measurement + template + class Measurement : public TraceType::type_t> > { public: @@ -392,37 +391,16 @@ namespace LLTrace : TraceType(name, description) {} - void sample(T value) - { - getPrimaryAccumulator().sample((storage_t)value); - } - }; - - template - class LL_COMMON_API Measurement - : public TraceType::type_t> > - { - public: - typedef typename LLUnits::HighestPrecisionType::type_t storage_t; - - Measurement(const char* name, const char* description = NULL) - : TraceType(name, description) - {} - template void sample(UNIT_T value) { - T converted_value; - converted_value = value; - getPrimaryAccumulator().sample((storage_t)converted_value.value()); + T converted_value(value); + getPrimaryAccumulator().sample((storage_t)converted_value); } }; - typedef TraceType > count_common_float_t; - typedef TraceType > count_common_int_t; - - template - class LL_COMMON_API Count + template + class Count : public TraceType::type_t> > { public: @@ -432,148 +410,12 @@ namespace LLTrace : TraceType(name) {} - void add(T value) - { - getPrimaryAccumulator().add((storage_t)value); - } - }; - - template - class LL_COMMON_API Count - : public TraceType::type_t> > - { - public: - typedef typename LLUnits::HighestPrecisionType::type_t storage_t; - - Count(const char* name, const char* description = NULL) - : TraceType(name) - {} - template void add(UNIT_T value) { - T converted_value; - converted_value = value; - getPrimaryAccumulator().add((storage_t)converted_value.value()); - } - }; - - class LL_COMMON_API TimerAccumulator - { - public: - typedef TimerAccumulator self_t; - - U32 mTotalTimeCounter, - mChildTimeCounter, - mCalls; - - TimerAccumulator* mParent; // info for caller timer - TimerAccumulator* mLastCaller; // used to bootstrap tree construction - const class BlockTimer* mTimer; // points to block timer associated with this storage - U8 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 - std::vector mChildren; // currently assumed child timers - - void addSamples(const TimerAccumulator& other) - { - mTotalTimeCounter += other.mTotalTimeCounter; - mChildTimeCounter += other.mChildTimeCounter; - mCalls += other.mCalls; - } - - void reset(const self_t* other) - { - mTotalTimeCounter = 0; - mChildTimeCounter = 0; - mCalls = 0; + T converted_value(value); + getPrimaryAccumulator().add((storage_t)converted_value); } - - }; - - class LL_COMMON_API BlockTimer : public TraceType - { - public: - BlockTimer(const char* name) - : TraceType(name) - {} - - struct Recorder - { - struct StackEntry - { - Recorder* mRecorder; - TimerAccumulator* mAccumulator; - U32 mChildTime; - }; - - LL_FORCE_INLINE Recorder(BlockTimer& block_timer) - : mLastRecorder(sCurRecorder) - { - mStartTime = getCPUClockCount32(); - TimerAccumulator* accumulator = &block_timer.getPrimaryAccumulator(); // get per-thread accumulator - accumulator->mActiveCount++; - accumulator->mCalls++; - accumulator->mMoveUpTree |= (accumulator->mParent->mActiveCount == 0); - - // push new timer on stack - sCurRecorder.mRecorder = this; - sCurRecorder.mAccumulator = accumulator; - sCurRecorder.mChildTime = 0; - } - - LL_FORCE_INLINE ~Recorder() - { - U32 total_time = getCPUClockCount32() - mStartTime; - - TimerAccumulator* accumulator = sCurRecorder.mAccumulator; - accumulator->mTotalTimeCounter += total_time; - accumulator->mChildTimeCounter += sCurRecorder.mChildTime; - accumulator->mActiveCount--; - - accumulator->mLastCaller = mLastRecorder.mAccumulator; - mLastRecorder.mChildTime += total_time; - - // pop stack - sCurRecorder = mLastRecorder; - } - - StackEntry mLastRecorder; - U32 mStartTime; - }; - - private: - static U32 getCPUClockCount32() - { - 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; - } - - // return full timer value, *not* shifted by 8 bits - static U64 getCPUClockCount64() - { - 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; - } - - static Recorder::StackEntry sCurRecorder; }; } -- cgit v1.2.3 From 9d77e030d9a0d23cebce616631677459eec1612c Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 14 Nov 2012 23:52:27 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system cleaning up build moved most includes of windows.h to llwin32headers.h to disable min/max macros, etc streamlined Time class and consolidated functionality in BlockTimer class llfasttimer is no longer included via llstring.h, so had to add it manually in several places --- indra/llcommon/lltrace.h | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index fb9dca5e84..61fed6e7b8 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -235,8 +235,8 @@ namespace LLTrace MeasurementAccumulator() : mSum(0), - mMin(std::numeric_limits::max()), - mMax(std::numeric_limits::min()), + mMin((std::numeric_limits::max)()), + mMax((std::numeric_limits::min)()), mMean(0), mVarianceSum(0), mNumSamples(0), @@ -380,6 +380,24 @@ namespace LLTrace U32 mNumSamples; }; + class TimerAccumulator + { + public: + void addSamples(const TimerAccumulator& other); + void reset(const TimerAccumulator* other); + + // + // members + // + U64 mSelfTimeCounter, + mTotalTimeCounter; + U32 mCalls; + class BlockTimer* mLastCaller; // used to bootstrap tree construction + 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 + }; + + template class Measurement : public TraceType::type_t> > -- cgit v1.2.3 From 6db6cb39f41e921e75970d1570a74cf35d353a35 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 16 Nov 2012 23:02:53 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system got new fast timer code to compile and run --- indra/llcommon/lltrace.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 61fed6e7b8..61d14569cd 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -67,6 +67,7 @@ namespace LLTrace void init(); void cleanup(); + bool isInitialized(); LLThreadLocalPointer& get_thread_recorder(); @@ -162,6 +163,10 @@ namespace LLTrace // NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned size_t reserveSlot() { + if (LLTrace::isInitialized()) + { + llerrs << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << llendl; + } size_t next_slot = mNextStorageSlot++; if (next_slot >= mStorageSize) { @@ -383,6 +388,7 @@ namespace LLTrace class TimerAccumulator { public: + TimerAccumulator(); void addSamples(const TimerAccumulator& other); void reset(const TimerAccumulator* other); -- cgit v1.2.3 From 1c894c05c10ef37be6507ee4bc4e9173506adfb6 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 27 Nov 2012 17:26:12 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system hunting down bad values and crashes --- indra/llcommon/lltrace.h | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 61d14569cd..11651ef953 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -107,6 +107,7 @@ namespace LLTrace //TODO pick another primary? sPrimaryStorage = NULL; } + delete[] mStorage; } LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index) -- cgit v1.2.3 From 02d503bf8f8890c6d4b57dd09a1fde2973715b75 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 29 Nov 2012 00:43:25 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system moved runtime timer tree topology information to separate array instead of recording stack --- indra/llcommon/lltrace.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 11651ef953..ad9f170aae 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -189,6 +189,11 @@ namespace LLTrace delete[] old_storage; } + size_t size() + { + return mNextStorageSlot; + } + static AccumulatorBuffer& getDefaultBuffer() { static AccumulatorBuffer sBuffer(STATIC_ALLOC); @@ -216,7 +221,7 @@ namespace LLTrace mAccumulatorIndex = AccumulatorBuffer::getDefaultBuffer().reserveSlot(); } - LL_FORCE_INLINE ACCUMULATOR& getPrimaryAccumulator() + LL_FORCE_INLINE ACCUMULATOR& getPrimaryAccumulator() const { return AccumulatorBuffer::getPrimaryStorage()[mAccumulatorIndex]; } @@ -399,6 +404,12 @@ namespace LLTrace U64 mSelfTimeCounter, mTotalTimeCounter; U32 mCalls; + }; + + class TimerTreeNode + { + public: + TimerTreeNode(); class BlockTimer* mLastCaller; // used to bootstrap tree construction 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 -- cgit v1.2.3 From ca2207bd35c33b13b122f875a5a7d218f94ca3fc Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sat, 1 Dec 2012 00:17:04 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system fixed scale of reported times moved reset calls to happen at same time so we don't show partial results --- indra/llcommon/lltrace.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index ad9f170aae..3e43a85e80 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -223,7 +223,8 @@ namespace LLTrace LL_FORCE_INLINE ACCUMULATOR& getPrimaryAccumulator() const { - return AccumulatorBuffer::getPrimaryStorage()[mAccumulatorIndex]; + ACCUMULATOR* accumulator_storage = AccumulatorBuffer::getPrimaryStorage(); + return accumulator_storage[mAccumulatorIndex]; } size_t getIndex() const { return mAccumulatorIndex; } -- cgit v1.2.3 From 407e5013f3845208e0a60e26e8f0a7fad997df5d Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 3 Dec 2012 19:54:53 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system converted fast timer view over to new lltrace mechanisms --- indra/llcommon/lltrace.h | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 3e43a85e80..9e275da647 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -37,7 +37,7 @@ #include -#define LL_RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder LL_GLUE_TOKENS(block_time_recorder, __COUNTER__)(block_timer); +#define LL_RECORD_BLOCK_TIME(block_timer) LLTrace::TimeBlock::Recorder LL_GLUE_TOKENS(block_time_recorder, __COUNTER__)(block_timer); namespace LLTrace { @@ -213,10 +213,10 @@ namespace LLTrace : public LLInstanceTracker, std::string> { public: - TraceType(const char* name, const char* description = NULL) + TraceType(const char* name, const char* description = "") : LLInstanceTracker(name), mName(name), - mDescription(description ? description : "") + mDescription(description) { mAccumulatorIndex = AccumulatorBuffer::getDefaultBuffer().reserveSlot(); } @@ -392,26 +392,43 @@ namespace LLTrace U32 mNumSamples; }; - class TimerAccumulator + class TimeBlockAccumulator { public: - TimerAccumulator(); - void addSamples(const TimerAccumulator& other); - void reset(const TimerAccumulator* other); + typedef LLUnit value_t; + + // fake class that allows us to view call count aspect of timeblock accumulator + struct CallCountAspect + { + typedef U32 value_t; + }; + + TimeBlockAccumulator(); + void addSamples(const TimeBlockAccumulator& other); + void reset(const TimeBlockAccumulator* other); // // members // U64 mSelfTimeCounter, mTotalTimeCounter; - U32 mCalls; + U32 mCalls; + }; + + template<> + class TraceType + : public TraceType + { + TraceType(const char* name, const char* description = "") + : TraceType(name, description) + {} }; - class TimerTreeNode + class TimeBlockTreeNode { public: - TimerTreeNode(); - class BlockTimer* mLastCaller; // used to bootstrap tree construction + TimeBlockTreeNode(); + class TimeBlock* mLastCaller; // used to bootstrap tree construction 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 }; -- cgit v1.2.3 From 6c7825107f6ebb3dd8697a52aeb5d29a93060dc4 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 4 Dec 2012 19:10:02 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system added copy constructor to periodic recording to allow snapshot generation in fast timer view fixed build errors --- indra/llcommon/lltrace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 9e275da647..a6b1b227c9 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -213,10 +213,10 @@ namespace LLTrace : public LLInstanceTracker, std::string> { public: - TraceType(const char* name, const char* description = "") + TraceType(const char* name, const char* description = NULL) : LLInstanceTracker(name), mName(name), - mDescription(description) + mDescription(description ? description : "") { mAccumulatorIndex = AccumulatorBuffer::getDefaultBuffer().reserveSlot(); } -- cgit v1.2.3 From 60800dacdd7e9b66ed654af471f2b9e9680cd981 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 6 Dec 2012 00:37:15 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system fixed gcc compile error made LLCopyOnWritePointer contain an LLPointer, not derive from it added type trait to control periodicrecording mean value type --- indra/llcommon/lltrace.h | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index a6b1b227c9..6e6bb51e47 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -201,18 +201,27 @@ namespace LLTrace } private: - ACCUMULATOR* mStorage; - size_t mStorageSize; - size_t mNextStorageSlot; + ACCUMULATOR* mStorage; + size_t mStorageSize; + size_t mNextStorageSlot; static LLThreadLocalPointer sPrimaryStorage; }; template LLThreadLocalPointer AccumulatorBuffer::sPrimaryStorage; + //TODO: replace with decltype when C++11 is enabled + template + struct MeanValueType + { + typedef F64 type; + }; + template class TraceType : public LLInstanceTracker, std::string> { public: + typedef typename MeanValueType >::type mean_t; + TraceType(const char* name, const char* description = NULL) : LLInstanceTracker(name), mName(name), @@ -415,6 +424,13 @@ namespace LLTrace U32 mCalls; }; + + template<> + struct MeanValueType > + { + typedef LLUnit type; + }; + template<> class TraceType : public TraceType -- cgit v1.2.3 From c99886d94389babc78e92bbfa5084fdd785915af Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 7 Dec 2012 15:20:12 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system improved unit tests for LLUnit renamed LLUnit to LLUnitImplicit with LLUnit being reserved for explicit units --- indra/llcommon/lltrace.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 6e6bb51e47..25d95d9670 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -435,6 +435,9 @@ namespace LLTrace class TraceType : public TraceType { + public: + typedef F32 mean_t; + TraceType(const char* name, const char* description = "") : TraceType(name, description) {} @@ -465,7 +468,7 @@ namespace LLTrace void sample(UNIT_T value) { T converted_value(value); - getPrimaryAccumulator().sample((storage_t)converted_value); + getPrimaryAccumulator().sample(LLUnits::rawValue(converted_value)); } }; @@ -484,7 +487,7 @@ namespace LLTrace void add(UNIT_T value) { T converted_value(value); - getPrimaryAccumulator().add((storage_t)converted_value); + getPrimaryAccumulator().add(LLUnits::rawValue(converted_value)); } }; } -- cgit v1.2.3 From c8c14ac72db3374cbd43893e5a97d98817cde0a3 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 7 Dec 2012 15:26:59 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system potential fixes for gcc builds --- indra/llcommon/lltrace.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 25d95d9670..0cb6a84aec 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -223,7 +223,7 @@ namespace LLTrace typedef typename MeanValueType >::type mean_t; TraceType(const char* name, const char* description = NULL) - : LLInstanceTracker(name), + : LLInstanceTracker, std::string>(name), mName(name), mDescription(description ? description : "") { @@ -459,16 +459,17 @@ namespace LLTrace { public: typedef typename LLUnits::HighestPrecisionType::type_t storage_t; + typedef TraceType::type_t> > trace_t; Measurement(const char* name, const char* description = NULL) - : TraceType(name, description) + : trace_t(name, description) {} template void sample(UNIT_T value) { T converted_value(value); - getPrimaryAccumulator().sample(LLUnits::rawValue(converted_value)); + trace_t::getPrimaryAccumulator().sample(LLUnits::rawValue(converted_value)); } }; @@ -478,16 +479,17 @@ namespace LLTrace { public: typedef typename LLUnits::HighestPrecisionType::type_t storage_t; + typedef TraceType::type_t> > trace_t; Count(const char* name, const char* description = NULL) - : TraceType(name) + : trace_t(name) {} template void add(UNIT_T value) { T converted_value(value); - getPrimaryAccumulator().add(LLUnits::rawValue(converted_value)); + trace_t::getPrimaryAccumulator().add(LLUnits::rawValue(converted_value)); } }; } -- cgit v1.2.3 From 8c2e3bea71ea15b805a9e2a288744f10d195d803 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sun, 9 Dec 2012 23:19:11 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system added ability to query self time of block timers indepedently --- indra/llcommon/lltrace.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 0cb6a84aec..d29d43a92c 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -412,6 +412,11 @@ namespace LLTrace typedef U32 value_t; }; + struct SelfTimeAspect + { + typedef LLUnit value_t; + }; + TimeBlockAccumulator(); void addSamples(const TimeBlockAccumulator& other); void reset(const TimeBlockAccumulator* other); @@ -443,6 +448,18 @@ namespace LLTrace {} }; + template<> + class TraceType + : public TraceType + { + public: + typedef F32 mean_t; + + TraceType(const char* name, const char* description = "") + : TraceType(name, description) + {} + }; + class TimeBlockTreeNode { public: -- cgit v1.2.3 From 1f56e57008f5a50c9e75fc0b4512c483ac359a52 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 18 Dec 2012 00:58:26 -0800 Subject: SH-3468 WIP add memory tracking base class created memory tracking trace type instrumented a few classes with memory tracking --- indra/llcommon/lltrace.h | 270 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 266 insertions(+), 4 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index d29d43a92c..d4fc93342d 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -424,9 +424,9 @@ namespace LLTrace // // members // - U64 mSelfTimeCounter, - mTotalTimeCounter; - U32 mCalls; + U64 mSelfTimeCounter, + mTotalTimeCounter; + U32 mCalls; }; @@ -509,6 +509,268 @@ namespace LLTrace trace_t::getPrimaryAccumulator().add(LLUnits::rawValue(converted_value)); } }; -} +struct MemStatAccumulator +{ + MemStatAccumulator() + : mSize(0), + mChildSize(0), + mAllocatedCount(0), + mDeallocatedCount(0) + {} + + void addSamples(const MemStatAccumulator& other) + { + mSize += other.mSize; + mChildSize += other.mChildSize; + mAllocatedCount += other.mAllocatedCount; + mDeallocatedCount += other.mDeallocatedCount; + } + + void reset(const MemStatAccumulator* other) + { + mSize = 0; + mChildSize = 0; + mAllocatedCount = 0; + mDeallocatedCount = 0; + } + + size_t mSize, + mChildSize; + int mAllocatedCount, + mDeallocatedCount; +}; + +class MemStat : public TraceType +{ +public: + typedef TraceType trace_t; + MemStat(const char* name) + : trace_t(name) + {} +}; + +// measures effective memory footprint of specified type +// specialize to cover different types + +template +struct MemFootprint +{ + static size_t measure(const T& value) + { + return sizeof(T); + } + + static size_t measure() + { + return sizeof(T); + } +}; + +template +struct MemFootprint +{ + static size_t measure(const T* value) + { + if (!value) + { + return 0; + } + return MemFootprint::measure(*value); + } + + static size_t measure() + { + return MemFootPrint::measure(); + } +}; + +template +struct MemFootprint > +{ + static size_t measure(const std::basic_string& value) + { + return value.capacity() * sizeof(T); + } + + static size_t measure() + { + return sizeof(std::basic_string); + } +}; + +template +struct MemFootprint > +{ + static size_t measure(const std::vector& value) + { + return value.capacity() * MemFootPrint::measure(); + } + + static size_t measure() + { + return sizeof(std::vector); + } +}; + +template +struct MemFootprint > +{ + static size_t measure(const std::list& value) + { + return value.size() * (MemFootPrint::measure() + sizeof(void*) * 2); + } + + static size_t measure() + { + return sizeof(std::list); + } +}; + +template +class MemTrackable +{ + template + struct TrackMemImpl; + + typedef MemTrackable mem_trackable_t; + +public: + typedef void mem_trackable_tag_t; + + ~MemTrackable() + { + memDisclaim(mMemFootprint); + } + + void* operator new(size_t allocation_size) + { + // reserve 8 bytes for allocation size (and preserving 8 byte alignment of structs) + void* allocation = ::operator new(allocation_size + 8); + *(size_t*)allocation = allocation_size; + MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); + accumulator.mSize += allocation_size; + accumulator.mAllocatedCount++; + return (void*)((char*)allocation + 8); + } + + void operator delete(void* ptr) + { + size_t* allocation_size = (size_t*)((char*)ptr - 8); + MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); + accumulator.mSize -= *allocation_size; + accumulator.mAllocatedCount--; + accumulator.mDeallocatedCount++; + ::delete((char*)ptr - 8); + } + + void *operator new [](size_t size) + { + size_t* result = (size_t*)malloc(size + 8); + *result = size; + MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); + accumulator.mSize += size; + accumulator.mAllocatedCount++; + return (void*)((char*)result + 8); + } + + void operator delete[](void* ptr) + { + size_t* allocation_size = (size_t*)((char*)ptr - 8); + MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); + accumulator.mSize -= *allocation_size; + accumulator.mAllocatedCount--; + accumulator.mDeallocatedCount++; + ::delete[]((char*)ptr - 8); + } + + // claim memory associated with other objects/data as our own, adding to our calculated footprint + template + T& memClaim(T& value) + { + TrackMemImpl::claim(*this, value); + return value; + } + + template + const T& memClaim(const T& value) + { + TrackMemImpl::claim(*this, value); + return value; + } + + + void memClaim(size_t size) + { + MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); + mMemFootprint += size; + accumulator.mSize += size; + } + + // remove memory we had claimed from our calculated footprint + template + T& memDisclaim(T& value) + { + TrackMemImpl::disclaim(*this, value); + return value; + } + + template + const T& memDisclaim(const T& value) + { + TrackMemImpl::disclaim(*this, value); + return value; + } + + void memDisclaim(size_t size) + { + MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); + accumulator.mSize -= size; + mMemFootprint -= size; + } + +private: + size_t mMemFootprint; + + template + struct TrackMemImpl + { + static void claim(mem_trackable_t& tracker, const TRACKED& tracked) + { + MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); + size_t footprint = MemFootprint::measure(tracked); + accumulator.mSize += footprint; + tracker.mMemFootprint += footprint; + } + + static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked) + { + MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); + size_t footprint = MemFootprint::measure(tracked); + accumulator.mSize -= footprint; + tracker.mMemFootprint -= footprint; + } + }; + + template + struct TrackMemImpl + { + static void claim(mem_trackable_t& tracker, TRACKED& tracked) + { + MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); + accumulator.mChildSize += MemFootprint::measure(tracked); + } + + static void disclaim(mem_trackable_t& tracker, TRACKED& tracked) + { + MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); + accumulator.mChildSize -= MemFootprint::measure(tracked); + } + }; + static MemStat sStat; +}; + +template MemStat MemTrackable::sStat(typeid(T).name()); + +} #endif // LL_LLTRACE_H -- cgit v1.2.3 From c219282f5de753a044cecb53bd806145f68add9a Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 18 Dec 2012 20:07:25 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system removed some potential data races got memory stats recording in trace system --- indra/llcommon/lltrace.h | 56 +++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 27 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index d4fc93342d..5b5e2b7879 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -82,18 +82,21 @@ namespace LLTrace enum StaticAllocationMarker { STATIC_ALLOC }; AccumulatorBuffer(StaticAllocationMarker m) - : mStorageSize(64), - mNextStorageSlot(0), - mStorage(new ACCUMULATOR[DEFAULT_ACCUMULATOR_BUFFER_SIZE]) - {} + : mStorageSize(0), + mStorage(NULL), + mNextStorageSlot(0) + { + resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE); + } public: AccumulatorBuffer(const AccumulatorBuffer& other = getDefaultBuffer()) - : mStorageSize(other.mStorageSize), - mStorage(new ACCUMULATOR[other.mStorageSize]), + : mStorageSize(0), + mStorage(NULL), mNextStorageSlot(other.mNextStorageSlot) { + resize(other.mStorageSize); for (S32 i = 0; i < mNextStorageSlot; i++) { mStorage[i] = other.mStorage[i]; @@ -181,9 +184,12 @@ namespace LLTrace { ACCUMULATOR* old_storage = mStorage; mStorage = new ACCUMULATOR[new_size]; - for (S32 i = 0; i < mStorageSize; i++) + if (old_storage) { - mStorage[i] = old_storage[i]; + for (S32 i = 0; i < mStorageSize; i++) + { + mStorage[i] = old_storage[i]; + } } mStorageSize = new_size; delete[] old_storage; @@ -300,14 +306,14 @@ namespace LLTrace mNumSamples += other.mNumSamples; mMean = mMean * weight + other.mMean * (1.f - weight); + // 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 sd_1 = getStandardDeviation(), sd_2 = other.getStandardDeviation(); - // 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 if (n_1 == 0) { mVarianceSum = other.mVarianceSum; @@ -405,6 +411,7 @@ namespace LLTrace { public: typedef LLUnit value_t; + typedef TimeBlockAccumulator self_t; // fake class that allows us to view call count aspect of timeblock accumulator struct CallCountAspect @@ -418,15 +425,20 @@ namespace LLTrace }; TimeBlockAccumulator(); - void addSamples(const TimeBlockAccumulator& other); - void reset(const TimeBlockAccumulator* other); + void addSamples(const self_t& other); + void reset(const self_t* other); // // members // - U64 mSelfTimeCounter, - mTotalTimeCounter; - U32 mCalls; + U64 mSelfTimeCounter, + mTotalTimeCounter; + U32 mCalls; + class TimeBlock* mParent; // last acknowledged parent of this time block + class TimeBlock* mLastCaller; // used to bootstrap tree construction + 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 + }; @@ -460,16 +472,6 @@ namespace LLTrace {} }; - class TimeBlockTreeNode - { - public: - TimeBlockTreeNode(); - class TimeBlock* mLastCaller; // used to bootstrap tree construction - 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 - }; - - template class Measurement : public TraceType::type_t> > @@ -604,7 +606,7 @@ struct MemFootprint > { static size_t measure(const std::vector& value) { - return value.capacity() * MemFootPrint::measure(); + return value.capacity() * MemFootprint::measure(); } static size_t measure() @@ -618,7 +620,7 @@ struct MemFootprint > { static size_t measure(const std::list& value) { - return value.size() * (MemFootPrint::measure() + sizeof(void*) * 2); + return value.size() * (MemFootprint::measure() + sizeof(void*) * 2); } static size_t measure() -- cgit v1.2.3 From 013f04cabec8e110ee659d9b3f75a4d25f114b7b Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 21 Dec 2012 00:13:21 -0800 Subject: SH-3468 WIP add memory tracking base class improvements on lifetime of lltrace core data structures tweaks to thread local pointer handling so that static constructors/destructors can safely call functions that use lltrace --- indra/llcommon/lltrace.h | 150 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 107 insertions(+), 43 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 5b5e2b7879..4bb19f6070 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -77,21 +77,21 @@ namespace LLTrace template class AccumulatorBuffer : public LLRefCount { + typedef AccumulatorBuffer self_t; static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64; private: - enum StaticAllocationMarker { STATIC_ALLOC }; + struct StaticAllocationMarker { }; AccumulatorBuffer(StaticAllocationMarker m) : mStorageSize(0), mStorage(NULL), mNextStorageSlot(0) { - resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE); } public: - AccumulatorBuffer(const AccumulatorBuffer& other = getDefaultBuffer()) + AccumulatorBuffer(const AccumulatorBuffer& other = *getDefaultBuffer()) : mStorageSize(0), mStorage(NULL), mNextStorageSlot(other.mNextStorageSlot) @@ -107,8 +107,7 @@ namespace LLTrace { if (sPrimaryStorage == mStorage) { - //TODO pick another primary? - sPrimaryStorage = NULL; + sPrimaryStorage = getDefaultBuffer()->mStorage; } delete[] mStorage; } @@ -182,6 +181,8 @@ namespace LLTrace void resize(size_t new_size) { + if (new_size <= mStorageSize) return; + ACCUMULATOR* old_storage = mStorage; mStorage = new ACCUMULATOR[new_size]; if (old_storage) @@ -193,16 +194,33 @@ namespace LLTrace } mStorageSize = new_size; delete[] old_storage; + + self_t* default_buffer = getDefaultBuffer(); + if (this != default_buffer + && new_size > default_buffer->size()) + { + //NB: this is not thread safe, but we assume that all resizing occurs during static initialization + default_buffer->resize(new_size); + } } - size_t size() + size_t size() const { return mNextStorageSlot; } - static AccumulatorBuffer& getDefaultBuffer() + static self_t* getDefaultBuffer() { - static AccumulatorBuffer sBuffer(STATIC_ALLOC); + // this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data + // so as not to trigger an access violation + //TODO: make this thread local but need to either demand-init apr or remove apr dependency + static self_t* sBuffer = new AccumulatorBuffer(StaticAllocationMarker()); + static bool sInitialized = false; + if (!sInitialized) + { + sBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE); + sInitialized = true; + } return sBuffer; } @@ -233,13 +251,13 @@ namespace LLTrace mName(name), mDescription(description ? description : "") { - mAccumulatorIndex = AccumulatorBuffer::getDefaultBuffer().reserveSlot(); + mAccumulatorIndex = AccumulatorBuffer::getDefaultBuffer()->reserveSlot(); } - LL_FORCE_INLINE ACCUMULATOR& getPrimaryAccumulator() const + LL_FORCE_INLINE ACCUMULATOR* getPrimaryAccumulator() const { ACCUMULATOR* accumulator_storage = AccumulatorBuffer::getPrimaryStorage(); - return accumulator_storage[mAccumulatorIndex]; + return &accumulator_storage[mAccumulatorIndex]; } size_t getIndex() const { return mAccumulatorIndex; } @@ -472,6 +490,22 @@ namespace LLTrace {} }; + class TimeBlock; + class TimeBlockTreeNode + { + public: + TimeBlockTreeNode(); + + void setParent(TimeBlock* parent); + TimeBlock* getParent() { return mParent; } + + TimeBlock* mBlock; + TimeBlock* mParent; + std::vector mChildren; + bool mNeedsSorting; + }; + + template class Measurement : public TraceType::type_t> > @@ -488,7 +522,7 @@ namespace LLTrace void sample(UNIT_T value) { T converted_value(value); - trace_t::getPrimaryAccumulator().sample(LLUnits::rawValue(converted_value)); + trace_t::getPrimaryAccumulator()->sample(LLUnits::rawValue(converted_value)); } }; @@ -508,7 +542,7 @@ namespace LLTrace void add(UNIT_T value) { T converted_value(value); - trace_t::getPrimaryAccumulator().add(LLUnits::rawValue(converted_value)); + trace_t::getPrimaryAccumulator()->add(LLUnits::rawValue(converted_value)); } }; @@ -650,19 +684,25 @@ public: // reserve 8 bytes for allocation size (and preserving 8 byte alignment of structs) void* allocation = ::operator new(allocation_size + 8); *(size_t*)allocation = allocation_size; - MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); - accumulator.mSize += allocation_size; - accumulator.mAllocatedCount++; + MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + if (accumulator) + { + accumulator->mSize += allocation_size; + accumulator->mAllocatedCount++; + } return (void*)((char*)allocation + 8); } void operator delete(void* ptr) { size_t* allocation_size = (size_t*)((char*)ptr - 8); - MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); - accumulator.mSize -= *allocation_size; - accumulator.mAllocatedCount--; - accumulator.mDeallocatedCount++; + MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + if (accumulator) + { + accumulator->mSize -= *allocation_size; + accumulator->mAllocatedCount--; + accumulator->mDeallocatedCount++; + } ::delete((char*)ptr - 8); } @@ -670,19 +710,25 @@ public: { size_t* result = (size_t*)malloc(size + 8); *result = size; - MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); - accumulator.mSize += size; - accumulator.mAllocatedCount++; + MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + if (accumulator) + { + accumulator->mSize += size; + accumulator->mAllocatedCount++; + } return (void*)((char*)result + 8); } void operator delete[](void* ptr) { size_t* allocation_size = (size_t*)((char*)ptr - 8); - MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); - accumulator.mSize -= *allocation_size; - accumulator.mAllocatedCount--; - accumulator.mDeallocatedCount++; + MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + if (accumulator) + { + accumulator->mSize -= *allocation_size; + accumulator->mAllocatedCount--; + accumulator->mDeallocatedCount++; + } ::delete[]((char*)ptr - 8); } @@ -704,9 +750,12 @@ public: void memClaim(size_t size) { - MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); mMemFootprint += size; - accumulator.mSize += size; + if (accumulator) + { + accumulator->mSize += size; + } } // remove memory we had claimed from our calculated footprint @@ -726,8 +775,11 @@ public: void memDisclaim(size_t size) { - MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); - accumulator.mSize -= size; + MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + if (accumulator) + { + accumulator->mSize -= size; + } mMemFootprint -= size; } @@ -739,18 +791,24 @@ private: { static void claim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); - size_t footprint = MemFootprint::measure(tracked); - accumulator.mSize += footprint; - tracker.mMemFootprint += footprint; + MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + if (accumulator) + { + size_t footprint = MemFootprint::measure(tracked); + accumulator->mSize += footprint; + tracker.mMemFootprint += footprint; + } } static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); - size_t footprint = MemFootprint::measure(tracked); - accumulator.mSize -= footprint; - tracker.mMemFootprint -= footprint; + MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + if (accumulator) + { + size_t footprint = MemFootprint::measure(tracked); + accumulator->mSize -= footprint; + tracker.mMemFootprint -= footprint; + } } }; @@ -759,14 +817,20 @@ private: { static void claim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); - accumulator.mChildSize += MemFootprint::measure(tracked); + MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + if (accumulator) + { + accumulator->mChildSize += MemFootprint::measure(tracked); + } } static void disclaim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator(); - accumulator.mChildSize -= MemFootprint::measure(tracked); + MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + if (accumulator) + { + accumulator->mChildSize -= MemFootprint::measure(tracked); + } } }; static MemStat sStat; -- cgit v1.2.3 From 3fd640a6e3dea7a3551c239323d782fb082e1dbd Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sun, 23 Dec 2012 12:27:25 -0800 Subject: SH-3468 WIP add memory tracking base class fixed crash on exit by making LLInstanceTracker iterators use atomic iterator nesting count for thread safety --- indra/llcommon/lltrace.h | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 4bb19f6070..05191cafaa 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -34,6 +34,7 @@ #include "llrefcount.h" #include "llunit.h" #include "llapr.h" +#include "llthreadlocalpointer.h" #include -- cgit v1.2.3 From cda2cdda511eb2f7a58e284db2c852fd4a3808ae Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 3 Jan 2013 00:30:54 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system made fast timer stack thread local added LLThreadLocalSingleton made LLThreadLocalPointer obey pointer rules for const added LLThreadLocalSingletonPointer for fast thread local pointers --- indra/llcommon/lltrace.h | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 05191cafaa..285d4389af 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -34,7 +34,7 @@ #include "llrefcount.h" #include "llunit.h" #include "llapr.h" -#include "llthreadlocalpointer.h" +#include "llthreadlocalstorage.h" #include @@ -70,7 +70,8 @@ namespace LLTrace void cleanup(); bool isInitialized(); - LLThreadLocalPointer& get_thread_recorder(); + const LLThreadLocalPointer& get_thread_recorder(); + void set_thread_recorder(class ThreadRecorder*); class MasterThreadRecorder& getMasterThreadRecorder(); @@ -106,9 +107,9 @@ namespace LLTrace ~AccumulatorBuffer() { - if (sPrimaryStorage == mStorage) + if (LLThreadLocalSingletonPointer::getInstance() == mStorage) { - sPrimaryStorage = getDefaultBuffer()->mStorage; + LLThreadLocalSingletonPointer::setInstance(getDefaultBuffer()->mStorage); } delete[] mStorage; } @@ -151,17 +152,17 @@ namespace LLTrace void makePrimary() { - sPrimaryStorage = mStorage; + LLThreadLocalSingletonPointer::setInstance(mStorage); } bool isPrimary() const { - return sPrimaryStorage == mStorage; + return LLThreadLocalSingletonPointer::getInstance() == mStorage; } LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage() { - return sPrimaryStorage.get(); + return LLThreadLocalSingletonPointer::getInstance(); } // NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned @@ -214,7 +215,6 @@ namespace LLTrace { // this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data // so as not to trigger an access violation - //TODO: make this thread local but need to either demand-init apr or remove apr dependency static self_t* sBuffer = new AccumulatorBuffer(StaticAllocationMarker()); static bool sInitialized = false; if (!sInitialized) @@ -229,9 +229,7 @@ namespace LLTrace ACCUMULATOR* mStorage; size_t mStorageSize; size_t mNextStorageSlot; - static LLThreadLocalPointer sPrimaryStorage; }; - template LLThreadLocalPointer AccumulatorBuffer::sPrimaryStorage; //TODO: replace with decltype when C++11 is enabled template @@ -250,10 +248,9 @@ namespace LLTrace TraceType(const char* name, const char* description = NULL) : LLInstanceTracker, std::string>(name), mName(name), - mDescription(description ? description : "") - { - mAccumulatorIndex = AccumulatorBuffer::getDefaultBuffer()->reserveSlot(); - } + mDescription(description ? description : ""), + mAccumulatorIndex(AccumulatorBuffer::getDefaultBuffer()->reserveSlot()) + {} LL_FORCE_INLINE ACCUMULATOR* getPrimaryAccumulator() const { @@ -263,13 +260,12 @@ namespace LLTrace size_t getIndex() const { return mAccumulatorIndex; } - std::string& getName() { return mName; } const std::string& getName() const { return mName; } protected: - std::string mName; - std::string mDescription; - size_t mAccumulatorIndex; + const std::string mName; + const std::string mDescription; + const size_t mAccumulatorIndex; }; template -- cgit v1.2.3 From 6e82bb7789c1e046dcfb97c6773150df110153f8 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 3 Jan 2013 22:34:34 +0000 Subject: fixing linux compile errors for llcommon after LLTrace work --- indra/llcommon/lltrace.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 285d4389af..e15cffd7d2 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -614,7 +614,7 @@ struct MemFootprint static size_t measure() { - return MemFootPrint::measure(); + return MemFootprint::measure(); } }; @@ -730,17 +730,17 @@ public: } // claim memory associated with other objects/data as our own, adding to our calculated footprint - template - T& memClaim(T& value) + template + CLAIM_T& memClaim(CLAIM_T& value) { - TrackMemImpl::claim(*this, value); + TrackMemImpl::claim(*this, value); return value; } - template - const T& memClaim(const T& value) + template + const CLAIM_T& memClaim(const CLAIM_T& value) { - TrackMemImpl::claim(*this, value); + TrackMemImpl::claim(*this, value); return value; } @@ -756,17 +756,17 @@ public: } // remove memory we had claimed from our calculated footprint - template - T& memDisclaim(T& value) + template + CLAIM_T& memDisclaim(CLAIM_T& value) { - TrackMemImpl::disclaim(*this, value); + TrackMemImpl::disclaim(*this, value); return value; } - template - const T& memDisclaim(const T& value) + template + const CLAIM_T& memDisclaim(const CLAIM_T& value) { - TrackMemImpl::disclaim(*this, value); + TrackMemImpl::disclaim(*this, value); return value; } -- cgit v1.2.3 From cbff0e7ab8afeebb6ddab854d35ea12ef9a9930a Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 4 Jan 2013 13:48:35 -0800 Subject: SH-3468 WIP add memory tracking base class attempted fix for gcc compile errors can't use typeid() on a class that doesn't have a method defined in a translation unit fix is to force classes deriving from LLMemTrackable to use their own static member named sMemStat --- indra/llcommon/lltrace.h | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index e15cffd7d2..1a156e583e 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -660,13 +660,13 @@ struct MemFootprint > } }; -template +template class MemTrackable { template struct TrackMemImpl; - typedef MemTrackable mem_trackable_t; + typedef MemTrackable mem_trackable_t; public: typedef void mem_trackable_tag_t; @@ -681,7 +681,7 @@ public: // reserve 8 bytes for allocation size (and preserving 8 byte alignment of structs) void* allocation = ::operator new(allocation_size + 8); *(size_t*)allocation = allocation_size; - MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize += allocation_size; @@ -693,7 +693,7 @@ public: void operator delete(void* ptr) { size_t* allocation_size = (size_t*)((char*)ptr - 8); - MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize -= *allocation_size; @@ -707,7 +707,7 @@ public: { size_t* result = (size_t*)malloc(size + 8); *result = size; - MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize += size; @@ -719,7 +719,7 @@ public: void operator delete[](void* ptr) { size_t* allocation_size = (size_t*)((char*)ptr - 8); - MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize -= *allocation_size; @@ -747,7 +747,7 @@ public: void memClaim(size_t size) { - MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); mMemFootprint += size; if (accumulator) { @@ -772,7 +772,7 @@ public: void memDisclaim(size_t size) { - MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize -= size; @@ -788,7 +788,7 @@ private: { static void claim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { size_t footprint = MemFootprint::measure(tracked); @@ -799,7 +799,7 @@ private: static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { size_t footprint = MemFootprint::measure(tracked); @@ -814,7 +814,7 @@ private: { static void claim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mChildSize += MemFootprint::measure(tracked); @@ -823,17 +823,14 @@ private: static void disclaim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator* accumulator = sStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mChildSize -= MemFootprint::measure(tracked); } } }; - static MemStat sStat; }; -template MemStat MemTrackable::sStat(typeid(T).name()); - } #endif // LL_LLTRACE_H -- cgit v1.2.3 From 1a888f786c274ee6eaed54272718eeef5e685dbf Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 9 Jan 2013 23:05:07 -0800 Subject: SH-3468 WIP add memory tracking base class made LLTrace::MemTrackable support custom alignment LLDrawable now uses MemTrackable new and delete operators --- indra/llcommon/lltrace.h | 85 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 71 insertions(+), 14 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 1a156e583e..8ec0cdc4dc 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -660,7 +660,57 @@ struct MemFootprint > } }; -template +template +void* allocAligned(size_t size) +{ + llstatic_assert((ALIGNMENT > 0) && (ALIGNMENT & (ALIGNMENT - 1)) == 0, "Alignment must be a power of 2"); + + void* padded_allocation; + const size_t aligned_reserve = (RESERVE / ALIGNMENT) + + ((RESERVE % ALIGNMENT) ? ALIGNMENT : 0); + const size_t size_with_reserve = size + aligned_reserve; + if (ALIGNMENT <= LL_DEFAULT_HEAP_ALIGN) + { + padded_allocation = malloc(size_with_reserve); + } + else + { +#if LL_WINDOWS + padded_allocation = _aligned_malloc(size_with_reserve, ALIGNMENT); +#elif LL_DARWIN + padded_allocation = ll_aligned_malloc(size_with_reserve, ALIGNMENT); +#else + posix_memalign(&padded_allocation, ALIGNMENT, size_with_reserve); +#endif + } + return (char*)padded_allocation + aligned_reserve; +} + +template +void deallocAligned(void* ptr) +{ + const size_t aligned_reserve = (RESERVE / ALIGNMENT) + + ((RESERVE % ALIGNMENT) ? ALIGNMENT : 0); + + void* original_allocation = (char*)ptr - aligned_reserve; + + if (ALIGNMENT <= LL_DEFAULT_HEAP_ALIGN) + { + free(original_allocation); + } + else + { +#if LL_WINDOWS + _aligned_free(original_allocation); +#elif LL_DARWIN + ll_aligned_free(original_allocation); +#else + free(original_allocation); +#endif + } +} + +template class MemTrackable { template @@ -676,44 +726,49 @@ public: memDisclaim(mMemFootprint); } - void* operator new(size_t allocation_size) + void* operator new(size_t size) { - // reserve 8 bytes for allocation size (and preserving 8 byte alignment of structs) - void* allocation = ::operator new(allocation_size + 8); - *(size_t*)allocation = allocation_size; MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { - accumulator->mSize += allocation_size; + accumulator->mSize += size; accumulator->mAllocatedCount++; } - return (void*)((char*)allocation + 8); + + // reserve 4 bytes for allocation size (and preserving requested alignment) + void* allocation = allocAligned(size); + ((size_t*)allocation)[-1] = size; + + return allocation; } void operator delete(void* ptr) { - size_t* allocation_size = (size_t*)((char*)ptr - 8); + size_t allocation_size = ((size_t*)ptr)[-1]; MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { - accumulator->mSize -= *allocation_size; + accumulator->mSize -= allocation_size; accumulator->mAllocatedCount--; accumulator->mDeallocatedCount++; } - ::delete((char*)ptr - 8); + deallocAligned(ptr); } void *operator new [](size_t size) { - size_t* result = (size_t*)malloc(size + 8); - *result = size; MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize += size; accumulator->mAllocatedCount++; } - return (void*)((char*)result + 8); + + // reserve 4 bytes for allocation size (and preserving requested alignment) + void* allocation = allocAligned(size); + ((size_t*)allocation)[-1] = size; + + return allocation; } void operator delete[](void* ptr) @@ -726,7 +781,7 @@ public: accumulator->mAllocatedCount--; accumulator->mDeallocatedCount++; } - ::delete[]((char*)ptr - 8); + deallocAligned(ptr); } // claim memory associated with other objects/data as our own, adding to our calculated footprint @@ -783,6 +838,8 @@ public: private: size_t mMemFootprint; + + template struct TrackMemImpl { -- cgit v1.2.3 From a891785f7a02098a53029311befd7083773d6ad8 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 10 Jan 2013 07:45:43 +0000 Subject: typo fix --- indra/llcommon/lltrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 8ec0cdc4dc..7694f65441 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -781,7 +781,7 @@ public: accumulator->mAllocatedCount--; accumulator->mDeallocatedCount++; } - deallocAligned(ptr); + deallocAligned(ptr); } // claim memory associated with other objects/data as our own, adding to our calculated footprint -- cgit v1.2.3 From 8c73ff245cee8da2ca75c5651be88a36358a5dae Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 10 Jan 2013 00:12:25 -0800 Subject: SH-3468 WIP add memory tracking base class actually use return value of posix_memalign! --- indra/llcommon/lltrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 7694f65441..a9d5cc58de 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -680,7 +680,7 @@ void* allocAligned(size_t size) #elif LL_DARWIN padded_allocation = ll_aligned_malloc(size_with_reserve, ALIGNMENT); #else - posix_memalign(&padded_allocation, ALIGNMENT, size_with_reserve); + padded_allocation = posix_memalign(&padded_allocation, ALIGNMENT, size_with_reserve); #endif } return (char*)padded_allocation + aligned_reserve; -- cgit v1.2.3 From f8a2bca6526ea1eef61a9b8cf0fb2e78c2663d60 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 10 Jan 2013 08:47:29 +0000 Subject: fix for invalid use of posix_memalign --- indra/llcommon/lltrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index a9d5cc58de..7694f65441 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -680,7 +680,7 @@ void* allocAligned(size_t size) #elif LL_DARWIN padded_allocation = ll_aligned_malloc(size_with_reserve, ALIGNMENT); #else - padded_allocation = posix_memalign(&padded_allocation, ALIGNMENT, size_with_reserve); + posix_memalign(&padded_allocation, ALIGNMENT, size_with_reserve); #endif } return (char*)padded_allocation + aligned_reserve; -- cgit v1.2.3 From d89d9cd10ff1fbe6f1f86f0b282075e775ed1b51 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 11 Jan 2013 01:52:09 +0000 Subject: gcc fixes --- indra/llcommon/lltrace.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 7694f65441..ab4ad59e3d 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -680,7 +680,8 @@ void* allocAligned(size_t size) #elif LL_DARWIN padded_allocation = ll_aligned_malloc(size_with_reserve, ALIGNMENT); #else - posix_memalign(&padded_allocation, ALIGNMENT, size_with_reserve); + if (LL_UNLIKELY(0 != posix_memalign(&padded_allocation, 16, size))) + padded_allocation = NULL; #endif } return (char*)padded_allocation + aligned_reserve; -- cgit v1.2.3 From 20b2fa4052ae6789ec8894f33f4764a1f7233b24 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 14 Jan 2013 23:08:01 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system improved performance of fast timer stat gathering --- indra/llcommon/lltrace.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index ab4ad59e3d..1d3c376a58 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -446,11 +446,12 @@ namespace LLTrace // // members // - U64 mSelfTimeCounter, + U64 mChildTimeCounter, mTotalTimeCounter; U32 mCalls; + class TimeBlock* mBlock; // block associated with this accumulator class TimeBlock* mParent; // last acknowledged parent of this time block - class TimeBlock* mLastCaller; // used to bootstrap tree construction + TimeBlockAccumulator* mLastAccumulator; // used to bootstrap tree construction 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 -- cgit v1.2.3 From e975ae35ab57f56adfaed64bc108240a5013f040 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 18 Jan 2013 15:59:16 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system fixed crash on startup --- indra/llcommon/lltrace.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 1d3c376a58..0f927bad53 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -449,9 +449,8 @@ namespace LLTrace U64 mChildTimeCounter, mTotalTimeCounter; U32 mCalls; - class TimeBlock* mBlock; // block associated with this accumulator class TimeBlock* mParent; // last acknowledged parent of this time block - TimeBlockAccumulator* mLastAccumulator; // used to bootstrap tree construction + class TimeBlock* mLastCaller; // used to bootstrap tree construction 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 -- cgit v1.2.3 From 2c68d5367c5c44aceb4ff23d9672c35642e030f7 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sun, 27 Jan 2013 21:35:20 -0800 Subject: SH-3275 WIP interesting Update viewer metrics system to be more flexible fixed memory leak fixed glitching of fast timer display --- indra/llcommon/lltrace.h | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 0f927bad53..c38e92962b 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -243,8 +243,6 @@ namespace LLTrace : public LLInstanceTracker, std::string> { public: - typedef typename MeanValueType >::type mean_t; - TraceType(const char* name, const char* description = NULL) : LLInstanceTracker, std::string>(name), mName(name), @@ -468,25 +466,37 @@ namespace LLTrace : public TraceType { public: - typedef F32 mean_t; TraceType(const char* name, const char* description = "") : TraceType(name, description) {} }; + template<> + struct MeanValueType > + { + typedef F64 type; + }; + + template<> class TraceType : public TraceType { public: - typedef F32 mean_t; TraceType(const char* name, const char* description = "") : TraceType(name, description) {} }; + template<> + struct MeanValueType > + { + typedef LLUnit type; + }; + + class TimeBlock; class TimeBlockTreeNode { -- cgit v1.2.3 From 438cbfe489cc34261ac600bbb22983164e59b1d9 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 7 Feb 2013 20:07:31 -0800 Subject: SH-3275 WIP interesting Update viewer metrics system to be more flexible fix for timings for recursive fast timers not being correct --- indra/llcommon/lltrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index c38e92962b..9eadd8a2be 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -445,7 +445,7 @@ namespace LLTrace // members // U64 mChildTimeCounter, - mTotalTimeCounter; + mSelfTimeCounter; U32 mCalls; class TimeBlock* mParent; // last acknowledged parent of this time block class TimeBlock* mLastCaller; // used to bootstrap tree construction -- cgit v1.2.3 From 2e15e8fd4ba62204c76f6e2a91d3e50f62e6c1fc Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sat, 9 Feb 2013 00:34:59 -0800 Subject: SH-3275 FIX interesting Update viewer metrics system to be more flexible fixed anamolous LLFastTimer timings --- indra/llcommon/lltrace.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 9eadd8a2be..8c3259eea9 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -444,7 +444,9 @@ namespace LLTrace // // members // - U64 mChildTimeCounter, + U64 mStartChildTimeCounter, + mStartSelfTimeCounter, + mChildTimeCounter, mSelfTimeCounter; U32 mCalls; class TimeBlock* mParent; // last acknowledged parent of this time block -- cgit v1.2.3 From 67ac6e7a294bd7401c55ed1d7423166dda1c0ee6 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sun, 10 Feb 2013 23:53:45 -0800 Subject: SH-3275 FIX interesting Update viewer metrics system to be more flexible streamlined fast timer delta tracking --- indra/llcommon/lltrace.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 8c3259eea9..5d57327a14 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -444,9 +444,8 @@ namespace LLTrace // // members // - U64 mStartChildTimeCounter, - mStartSelfTimeCounter, - mChildTimeCounter, + U64 mStartTotalTimeCounter, + mTotalTimeCounter, mSelfTimeCounter; U32 mCalls; class TimeBlock* mParent; // last acknowledged parent of this time block -- cgit v1.2.3 From f07b9c2c69f1f6882dcf249aacf33cdfacf878ab Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 6 Mar 2013 11:08:25 -0800 Subject: renamed LLTrace stat gathering classes/methods to make the structure of LLTrace clearer Count becomes CountStatHandle Count.sum becomes sum(Count, value), etc. --- indra/llcommon/lltrace.h | 832 ++++++++++++++++++++++++----------------------- 1 file changed, 417 insertions(+), 415 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 5d57327a14..44da1939c6 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -42,517 +42,519 @@ namespace LLTrace { - class Recording; - - typedef LLUnit Bytes; - typedef LLUnit Kilobytes; - typedef LLUnit Megabytes; - typedef LLUnit Gigabytes; - typedef LLUnit Bits; - typedef LLUnit Kilobits; - typedef LLUnit Megabits; - typedef LLUnit Gigabits; - - typedef LLUnit Seconds; - typedef LLUnit Milliseconds; - typedef LLUnit Minutes; - typedef LLUnit Hours; - typedef LLUnit Milliseconds; - typedef LLUnit Microseconds; - typedef LLUnit Nanoseconds; - - typedef LLUnit Meters; - typedef LLUnit Kilometers; - typedef LLUnit Centimeters; - typedef LLUnit Millimeters; - - void init(); - void cleanup(); - bool isInitialized(); - - const LLThreadLocalPointer& get_thread_recorder(); - void set_thread_recorder(class ThreadRecorder*); - - class MasterThreadRecorder& getMasterThreadRecorder(); - - // one per thread per type - template - class AccumulatorBuffer : public LLRefCount - { - typedef AccumulatorBuffer self_t; - static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64; - private: - struct StaticAllocationMarker { }; - - AccumulatorBuffer(StaticAllocationMarker m) - : mStorageSize(0), - mStorage(NULL), - mNextStorageSlot(0) - { - } +class Recording; + +typedef LLUnit Bytes; +typedef LLUnit Kilobytes; +typedef LLUnit Megabytes; +typedef LLUnit Gigabytes; +typedef LLUnit Bits; +typedef LLUnit Kilobits; +typedef LLUnit Megabits; +typedef LLUnit Gigabits; + +typedef LLUnit Seconds; +typedef LLUnit Milliseconds; +typedef LLUnit Minutes; +typedef LLUnit Hours; +typedef LLUnit Milliseconds; +typedef LLUnit Microseconds; +typedef LLUnit Nanoseconds; + +typedef LLUnit Meters; +typedef LLUnit Kilometers; +typedef LLUnit Centimeters; +typedef LLUnit Millimeters; + +void init(); +void cleanup(); +bool isInitialized(); + +const LLThreadLocalPointer& get_thread_recorder(); +void set_thread_recorder(class ThreadRecorder*); + +class MasterThreadRecorder& getMasterThreadRecorder(); + +// one per thread per type +template +class AccumulatorBuffer : public LLRefCount +{ + typedef AccumulatorBuffer self_t; + static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64; +private: + struct StaticAllocationMarker { }; - public: + AccumulatorBuffer(StaticAllocationMarker m) + : mStorageSize(0), + mStorage(NULL), + mNextStorageSlot(0) + { + } - AccumulatorBuffer(const AccumulatorBuffer& other = *getDefaultBuffer()) - : mStorageSize(0), - mStorage(NULL), - mNextStorageSlot(other.mNextStorageSlot) - { - resize(other.mStorageSize); - for (S32 i = 0; i < mNextStorageSlot; i++) - { - mStorage[i] = other.mStorage[i]; - } - } +public: - ~AccumulatorBuffer() + AccumulatorBuffer(const AccumulatorBuffer& other = *getDefaultBuffer()) + : mStorageSize(0), + mStorage(NULL), + mNextStorageSlot(other.mNextStorageSlot) + { + resize(other.mStorageSize); + for (S32 i = 0; i < mNextStorageSlot; i++) { - if (LLThreadLocalSingletonPointer::getInstance() == mStorage) - { - LLThreadLocalSingletonPointer::setInstance(getDefaultBuffer()->mStorage); - } - delete[] mStorage; + mStorage[i] = other.mStorage[i]; } + } - LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index) - { - return mStorage[index]; + ~AccumulatorBuffer() + { + if (LLThreadLocalSingletonPointer::getInstance() == mStorage) + { + LLThreadLocalSingletonPointer::setInstance(getDefaultBuffer()->mStorage); } + delete[] mStorage; + } - LL_FORCE_INLINE const ACCUMULATOR& operator[](size_t index) const - { - return mStorage[index]; - } + LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index) + { + return mStorage[index]; + } - void addSamples(const AccumulatorBuffer& other) - { - llassert(mNextStorageSlot == other.mNextStorageSlot); + LL_FORCE_INLINE const ACCUMULATOR& operator[](size_t index) const + { + return mStorage[index]; + } - for (size_t i = 0; i < mNextStorageSlot; i++) - { - mStorage[i].addSamples(other.mStorage[i]); - } - } + void addSamples(const AccumulatorBuffer& other) + { + llassert(mNextStorageSlot == other.mNextStorageSlot); - void copyFrom(const AccumulatorBuffer& other) + for (size_t i = 0; i < mNextStorageSlot; i++) { - for (size_t i = 0; i < mNextStorageSlot; i++) - { - mStorage[i] = other.mStorage[i]; - } + mStorage[i].addSamples(other.mStorage[i]); } + } - void reset(const AccumulatorBuffer* other = NULL) + void copyFrom(const AccumulatorBuffer& other) + { + for (size_t i = 0; i < mNextStorageSlot; i++) { - for (size_t i = 0; i < mNextStorageSlot; i++) - { - mStorage[i].reset(other ? &other->mStorage[i] : NULL); - } + mStorage[i] = other.mStorage[i]; } + } - void makePrimary() + void reset(const AccumulatorBuffer* other = NULL) + { + for (size_t i = 0; i < mNextStorageSlot; i++) { - LLThreadLocalSingletonPointer::setInstance(mStorage); + mStorage[i].reset(other ? &other->mStorage[i] : NULL); } + } - bool isPrimary() const - { - return LLThreadLocalSingletonPointer::getInstance() == mStorage; - } + void makePrimary() + { + LLThreadLocalSingletonPointer::setInstance(mStorage); + } - LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage() - { - return LLThreadLocalSingletonPointer::getInstance(); - } + bool isPrimary() const + { + return LLThreadLocalSingletonPointer::getInstance() == mStorage; + } - // NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned - size_t reserveSlot() + LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage() + { + return LLThreadLocalSingletonPointer::getInstance(); + } + + // NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned + size_t reserveSlot() + { + if (LLTrace::isInitialized()) { - if (LLTrace::isInitialized()) - { - llerrs << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << llendl; - } - size_t next_slot = mNextStorageSlot++; - if (next_slot >= mStorageSize) - { - resize(mStorageSize + (mStorageSize >> 2)); - } - llassert(mStorage && next_slot < mStorageSize); - return next_slot; + llerrs << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << llendl; } - - void resize(size_t new_size) + size_t next_slot = mNextStorageSlot++; + if (next_slot >= mStorageSize) { - if (new_size <= mStorageSize) return; + resize(mStorageSize + (mStorageSize >> 2)); + } + llassert(mStorage && next_slot < mStorageSize); + return next_slot; + } - ACCUMULATOR* old_storage = mStorage; - mStorage = new ACCUMULATOR[new_size]; - if (old_storage) - { - for (S32 i = 0; i < mStorageSize; i++) - { - mStorage[i] = old_storage[i]; - } - } - mStorageSize = new_size; - delete[] old_storage; + void resize(size_t new_size) + { + if (new_size <= mStorageSize) return; - self_t* default_buffer = getDefaultBuffer(); - if (this != default_buffer - && new_size > default_buffer->size()) + ACCUMULATOR* old_storage = mStorage; + mStorage = new ACCUMULATOR[new_size]; + if (old_storage) + { + for (S32 i = 0; i < mStorageSize; i++) { - //NB: this is not thread safe, but we assume that all resizing occurs during static initialization - default_buffer->resize(new_size); + mStorage[i] = old_storage[i]; } } + mStorageSize = new_size; + delete[] old_storage; - size_t size() const + self_t* default_buffer = getDefaultBuffer(); + if (this != default_buffer + && new_size > default_buffer->size()) { - return mNextStorageSlot; + //NB: this is not thread safe, but we assume that all resizing occurs during static initialization + default_buffer->resize(new_size); } + } + + size_t size() const + { + return mNextStorageSlot; + } - static self_t* getDefaultBuffer() + static self_t* getDefaultBuffer() + { + // this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data + // so as not to trigger an access violation + static self_t* sBuffer = new AccumulatorBuffer(StaticAllocationMarker()); + static bool sInitialized = false; + if (!sInitialized) { - // this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data - // so as not to trigger an access violation - static self_t* sBuffer = new AccumulatorBuffer(StaticAllocationMarker()); - static bool sInitialized = false; - if (!sInitialized) - { - sBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE); - sInitialized = true; - } - return sBuffer; + sBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE); + sInitialized = true; } + return sBuffer; + } - private: - ACCUMULATOR* mStorage; - size_t mStorageSize; - size_t mNextStorageSlot; - }; +private: + ACCUMULATOR* mStorage; + size_t mStorageSize; + size_t mNextStorageSlot; +}; - //TODO: replace with decltype when C++11 is enabled - template - struct MeanValueType - { - typedef F64 type; - }; +//TODO: replace with decltype when C++11 is enabled +template +struct MeanValueType +{ + typedef F64 type; +}; - template - class TraceType - : public LLInstanceTracker, std::string> +template +class TraceType +: public LLInstanceTracker, std::string> +{ +public: + TraceType(const char* name, const char* description = NULL) + : LLInstanceTracker, std::string>(name), + mName(name), + mDescription(description ? description : ""), + mAccumulatorIndex(AccumulatorBuffer::getDefaultBuffer()->reserveSlot()) + {} + + LL_FORCE_INLINE ACCUMULATOR* getPrimaryAccumulator() const { - public: - TraceType(const char* name, const char* description = NULL) - : LLInstanceTracker, std::string>(name), - mName(name), - mDescription(description ? description : ""), - mAccumulatorIndex(AccumulatorBuffer::getDefaultBuffer()->reserveSlot()) - {} + ACCUMULATOR* accumulator_storage = AccumulatorBuffer::getPrimaryStorage(); + return &accumulator_storage[mAccumulatorIndex]; + } - LL_FORCE_INLINE ACCUMULATOR* getPrimaryAccumulator() const - { - ACCUMULATOR* accumulator_storage = AccumulatorBuffer::getPrimaryStorage(); - return &accumulator_storage[mAccumulatorIndex]; - } + size_t getIndex() const { return mAccumulatorIndex; } - size_t getIndex() const { return mAccumulatorIndex; } + const std::string& getName() const { return mName; } - const std::string& getName() const { return mName; } +protected: + const std::string mName; + const std::string mDescription; + const size_t mAccumulatorIndex; +}; - protected: - const std::string mName; - const std::string mDescription; - const size_t mAccumulatorIndex; - }; +template +class MeasurementAccumulator +{ +public: + typedef T value_t; + typedef MeasurementAccumulator self_t; + + MeasurementAccumulator() + : mSum(0), + mMin((std::numeric_limits::max)()), + mMax((std::numeric_limits::min)()), + mMean(0), + mVarianceSum(0), + mNumSamples(0), + mLastValue(0) + {} - template - class MeasurementAccumulator + void sample(T value) { - public: - typedef T value_t; - typedef MeasurementAccumulator self_t; - - MeasurementAccumulator() - : mSum(0), - mMin((std::numeric_limits::max)()), - mMax((std::numeric_limits::min)()), - mMean(0), - mVarianceSum(0), - mNumSamples(0), - mLastValue(0) - {} + mNumSamples++; + mSum += value; + if (value < mMin) + { + mMin = value; + } + if (value > mMax) + { + mMax = value; + } + F64 old_mean = mMean; + mMean += ((F64)value - old_mean) / (F64)mNumSamples; + mVarianceSum += ((F64)value - old_mean) * ((F64)value - mMean); + mLastValue = value; + } - LL_FORCE_INLINE void sample(T value) + void addSamples(const self_t& other) + { + if (other.mNumSamples) { - T storage_value(value); - mNumSamples++; - mSum += storage_value; - if (storage_value < mMin) + mSum += other.mSum; + if (other.mMin < mMin) { - mMin = storage_value; + mMin = other.mMin; } - if (storage_value > mMax) + if (other.mMax > mMax) { - mMax = storage_value; + mMax = other.mMax; } - F64 old_mean = mMean; - mMean += ((F64)storage_value - old_mean) / (F64)mNumSamples; - mVarianceSum += ((F64)storage_value - old_mean) * ((F64)storage_value - mMean); - mLastValue = storage_value; - } - - void addSamples(const self_t& other) - { - if (other.mNumSamples) + F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples); + mNumSamples += other.mNumSamples; + mMean = mMean * weight + other.mMean * (1.f - weight); + + // 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 = mVarianceSum / mNumSamples, + v_2 = other.mVarianceSum / other.mNumSamples; + if (n_1 == 0) + { + mVarianceSum = other.mVarianceSum; + } + else if (n_2 == 0) { - mSum += other.mSum; - if (other.mMin < mMin) - { - mMin = other.mMin; - } - if (other.mMax > mMax) - { - mMax = other.mMax; - } - F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples); - mNumSamples += other.mNumSamples; - mMean = mMean * weight + other.mMean * (1.f - weight); - - // 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 sd_1 = getStandardDeviation(), - sd_2 = other.getStandardDeviation(); - if (n_1 == 0) - { - mVarianceSum = other.mVarianceSum; - } - else if (n_2 == 0) - { - // don't touch variance - // mVarianceSum = mVarianceSum; - } - else - { - 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)) - * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2)))) - / (n_1 + n_2 - 1.f)); - } - mLastValue = other.mLastValue; + // don't touch variance + // mVarianceSum = mVarianceSum; } + else + { + mVarianceSum = (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)); + } + mLastValue = other.mLastValue; } + } - void reset(const self_t* other) - { - mNumSamples = 0; - mSum = 0; - mMin = 0; - mMax = 0; - mMean = 0; - mVarianceSum = 0; - mLastValue = other ? other->mLastValue : 0; - } + void reset(const self_t* other) + { + mNumSamples = 0; + mSum = 0; + mMin = 0; + mMax = 0; + mMean = 0; + mVarianceSum = 0; + mLastValue = other ? other->mLastValue : 0; + } - 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; } + 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; } - private: - T mSum, - mMin, - mMax, - mLastValue; +private: + T mSum, + mMin, + mMax, + mLastValue; - F64 mMean, - mVarianceSum; + F64 mMean, + mVarianceSum; - U32 mNumSamples; - }; + U32 mNumSamples; +}; + +template +class CountAccumulator +{ +public: + typedef CountAccumulator self_t; + typedef T value_t; + + CountAccumulator() + : mSum(0), + mNumSamples(0) + {} - template - class CountAccumulator + void add(T value) { - public: - typedef CountAccumulator self_t; - typedef T value_t; + mNumSamples++; + mSum += value; + } - CountAccumulator() - : mSum(0), - mNumSamples(0) - {} + void addSamples(const CountAccumulator& other) + { + mSum += other.mSum; + mNumSamples += other.mNumSamples; + } - LL_FORCE_INLINE void add(T value) - { - mNumSamples++; - mSum += value; - } + void reset(const self_t* other) + { + mNumSamples = 0; + mSum = 0; + } - void addSamples(const CountAccumulator& other) - { - mSum += other.mSum; - mNumSamples += other.mNumSamples; - } + T getSum() const { return (T)mSum; } - void reset(const self_t* other) - { - mNumSamples = 0; - mSum = 0; - } + U32 getSampleCount() const { return mNumSamples; } - T getSum() const { return (T)mSum; } +private: + T mSum; - U32 getSampleCount() const { return mNumSamples; } + U32 mNumSamples; +}; - private: - T mSum; +class TimeBlockAccumulator +{ +public: + typedef LLUnit value_t; + typedef TimeBlockAccumulator self_t; - U32 mNumSamples; + // fake class that allows us to view call count aspect of timeblock accumulator + struct CallCountAspect + { + typedef U32 value_t; }; - class TimeBlockAccumulator + struct SelfTimeAspect { - public: typedef LLUnit value_t; - typedef TimeBlockAccumulator self_t; + }; - // fake class that allows us to view call count aspect of timeblock accumulator - struct CallCountAspect - { - typedef U32 value_t; - }; + TimeBlockAccumulator(); + void addSamples(const self_t& other); + void reset(const self_t* other); + + // + // members + // + U64 mStartTotalTimeCounter, + mTotalTimeCounter, + mSelfTimeCounter; + U32 mCalls; + class TimeBlock* mParent; // last acknowledged parent of this time block + class TimeBlock* mLastCaller; // used to bootstrap tree construction + 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 - struct SelfTimeAspect - { - typedef LLUnit value_t; - }; - - TimeBlockAccumulator(); - void addSamples(const self_t& other); - void reset(const self_t* other); - - // - // members - // - U64 mStartTotalTimeCounter, - mTotalTimeCounter, - mSelfTimeCounter; - U32 mCalls; - class TimeBlock* mParent; // last acknowledged parent of this time block - class TimeBlock* mLastCaller; // used to bootstrap tree construction - 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 +}; - }; +template<> +struct MeanValueType > +{ + typedef LLUnit type; +}; - template<> - struct MeanValueType > - { - typedef LLUnit type; - }; +template<> +class TraceType +: public TraceType +{ +public: - template<> - class TraceType + TraceType(const char* name, const char* description = "") + : TraceType(name, description) + {} +}; + +template<> +struct MeanValueType > +{ + typedef F64 type; +}; + + +template<> +class TraceType : public TraceType - { - public: +{ +public: - TraceType(const char* name, const char* description = "") + TraceType(const char* name, const char* description = "") : TraceType(name, description) - {} - }; - - template<> - struct MeanValueType > - { - typedef F64 type; - }; + {} +}; +template<> +struct MeanValueType > +{ + typedef LLUnit type; +}; - template<> - class TraceType - : public TraceType - { - public: - TraceType(const char* name, const char* description = "") - : TraceType(name, description) - {} - }; +class TimeBlock; +class TimeBlockTreeNode +{ +public: + TimeBlockTreeNode(); - template<> - struct MeanValueType > - { - typedef LLUnit type; - }; + void setParent(TimeBlock* parent); + TimeBlock* getParent() { return mParent; } + TimeBlock* mBlock; + TimeBlock* mParent; + std::vector mChildren; + bool mNeedsSorting; +}; - class TimeBlock; - class TimeBlockTreeNode - { - public: - TimeBlockTreeNode(); - void setParent(TimeBlock* parent); - TimeBlock* getParent() { return mParent; } +template +class MeasurementStatHandle +: public TraceType::type_t> > +{ +public: + typedef typename LLUnits::HighestPrecisionType::type_t storage_t; + typedef TraceType::type_t> > trace_t; - TimeBlock* mBlock; - TimeBlock* mParent; - std::vector mChildren; - bool mNeedsSorting; - }; + MeasurementStatHandle(const char* name, const char* description = NULL) + : trace_t(name, description) + {} +}; +template +void sample(MeasurementStatHandle& measurement, VALUE_T value) +{ + T converted_value(value); + measurement.getPrimaryAccumulator()->sample(LLUnits::rawValue(converted_value)); +} - template - class Measurement - : public TraceType::type_t> > - { - public: - typedef typename LLUnits::HighestPrecisionType::type_t storage_t; - typedef TraceType::type_t> > trace_t; - Measurement(const char* name, const char* description = NULL) - : trace_t(name, description) - {} +template +class CountStatHandle +: public TraceType::type_t> > +{ +public: + typedef typename LLUnits::HighestPrecisionType::type_t storage_t; + typedef TraceType::type_t> > trace_t; - template - void sample(UNIT_T value) - { - T converted_value(value); - trace_t::getPrimaryAccumulator()->sample(LLUnits::rawValue(converted_value)); - } - }; + CountStatHandle(const char* name, const char* description = NULL) + : trace_t(name) + {} - template - class Count - : public TraceType::type_t> > - { - public: - typedef typename LLUnits::HighestPrecisionType::type_t storage_t; - typedef TraceType::type_t> > trace_t; +}; - Count(const char* name, const char* description = NULL) - : trace_t(name) - {} +template +void add(CountStatHandle& count, VALUE_T value) +{ + T converted_value(value); + count.getPrimaryAccumulator()->add(LLUnits::rawValue(converted_value)); +} - template - void add(UNIT_T value) - { - T converted_value(value); - trace_t::getPrimaryAccumulator()->add(LLUnits::rawValue(converted_value)); - } - }; struct MemStatAccumulator { @@ -585,11 +587,11 @@ struct MemStatAccumulator mDeallocatedCount; }; -class MemStat : public TraceType +class MemStatHandle : public TraceType { public: typedef TraceType trace_t; - MemStat(const char* name) + MemStatHandle(const char* name) : trace_t(name) {} }; -- cgit v1.2.3 From 1a256eca280e41a672fc87e083db851ab180612c Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 11 Mar 2013 00:37:50 -0700 Subject: renamed some variables/methods in LLTrace to make things clearer --- indra/llcommon/lltrace.h | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 44da1939c6..9bca3625b6 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -287,6 +287,7 @@ public: { mNumSamples++; mSum += value; + // NOTE: both conditions will hold on first pass through if (value < mMin) { mMin = value; -- cgit v1.2.3 From 78f60fad0e4608cb996ee9cba8e4d10d3893f54d Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 18 Mar 2013 23:37:57 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics cleaned up MemTrackable stats to not use special padded allocation --- indra/llcommon/lltrace.h | 81 ++++++------------------------------------------ 1 file changed, 9 insertions(+), 72 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 9bca3625b6..71bf1e53e4 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -674,57 +674,6 @@ struct MemFootprint > } }; -template -void* allocAligned(size_t size) -{ - llstatic_assert((ALIGNMENT > 0) && (ALIGNMENT & (ALIGNMENT - 1)) == 0, "Alignment must be a power of 2"); - - void* padded_allocation; - const size_t aligned_reserve = (RESERVE / ALIGNMENT) - + ((RESERVE % ALIGNMENT) ? ALIGNMENT : 0); - const size_t size_with_reserve = size + aligned_reserve; - if (ALIGNMENT <= LL_DEFAULT_HEAP_ALIGN) - { - padded_allocation = malloc(size_with_reserve); - } - else - { -#if LL_WINDOWS - padded_allocation = _aligned_malloc(size_with_reserve, ALIGNMENT); -#elif LL_DARWIN - padded_allocation = ll_aligned_malloc(size_with_reserve, ALIGNMENT); -#else - if (LL_UNLIKELY(0 != posix_memalign(&padded_allocation, 16, size))) - padded_allocation = NULL; -#endif - } - return (char*)padded_allocation + aligned_reserve; -} - -template -void deallocAligned(void* ptr) -{ - const size_t aligned_reserve = (RESERVE / ALIGNMENT) - + ((RESERVE % ALIGNMENT) ? ALIGNMENT : 0); - - void* original_allocation = (char*)ptr - aligned_reserve; - - if (ALIGNMENT <= LL_DEFAULT_HEAP_ALIGN) - { - free(original_allocation); - } - else - { -#if LL_WINDOWS - _aligned_free(original_allocation); -#elif LL_DARWIN - ll_aligned_free(original_allocation); -#else - free(original_allocation); -#endif - } -} - template class MemTrackable { @@ -736,7 +685,7 @@ class MemTrackable public: typedef void mem_trackable_tag_t; - ~MemTrackable() + virtual ~MemTrackable() { memDisclaim(mMemFootprint); } @@ -750,24 +699,19 @@ public: accumulator->mAllocatedCount++; } - // reserve 4 bytes for allocation size (and preserving requested alignment) - void* allocation = allocAligned(size); - ((size_t*)allocation)[-1] = size; - - return allocation; + return ::operator new(size); } - void operator delete(void* ptr) + void operator delete(void* ptr, size_t size) { - size_t allocation_size = ((size_t*)ptr)[-1]; MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { - accumulator->mSize -= allocation_size; + accumulator->mSize -= size; accumulator->mAllocatedCount--; accumulator->mDeallocatedCount++; } - deallocAligned(ptr); + ::operator delete(ptr); } void *operator new [](size_t size) @@ -779,24 +723,19 @@ public: accumulator->mAllocatedCount++; } - // reserve 4 bytes for allocation size (and preserving requested alignment) - void* allocation = allocAligned(size); - ((size_t*)allocation)[-1] = size; - - return allocation; + return ::operator new[](size); } - void operator delete[](void* ptr) + void operator delete[](void* ptr, size_t size) { - size_t* allocation_size = (size_t*)((char*)ptr - 8); MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { - accumulator->mSize -= *allocation_size; + accumulator->mSize -= size; accumulator->mAllocatedCount--; accumulator->mDeallocatedCount++; } - deallocAligned(ptr); + ::operator delete[](ptr); } // claim memory associated with other objects/data as our own, adding to our calculated footprint @@ -853,8 +792,6 @@ public: private: size_t mMemFootprint; - - template struct TrackMemImpl { -- cgit v1.2.3 From 935dce7d6b0a343cef5b13f53d6da5d0c2dc6a73 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 25 Mar 2013 00:18:06 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics fixed some compile errors made label spacing automatic on stat bars fixed infinite values coming from stats --- indra/llcommon/lltrace.h | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 71bf1e53e4..a574be02da 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -86,20 +86,17 @@ private: AccumulatorBuffer(StaticAllocationMarker m) : mStorageSize(0), - mStorage(NULL), - mNextStorageSlot(0) - { - } + mStorage(NULL) + {} public: AccumulatorBuffer(const AccumulatorBuffer& other = *getDefaultBuffer()) : mStorageSize(0), - mStorage(NULL), - mNextStorageSlot(other.mNextStorageSlot) + mStorage(NULL) { resize(other.mStorageSize); - for (S32 i = 0; i < mNextStorageSlot; i++) + for (S32 i = 0; i < sNextStorageSlot; i++) { mStorage[i] = other.mStorage[i]; } @@ -126,9 +123,8 @@ public: void addSamples(const AccumulatorBuffer& other) { - llassert(mNextStorageSlot == other.mNextStorageSlot); - - for (size_t i = 0; i < mNextStorageSlot; i++) + llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize > sNextStorageSlot); + for (size_t i = 0; i < sNextStorageSlot; i++) { mStorage[i].addSamples(other.mStorage[i]); } @@ -136,7 +132,8 @@ public: void copyFrom(const AccumulatorBuffer& other) { - for (size_t i = 0; i < mNextStorageSlot; i++) + llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize > sNextStorageSlot); + for (size_t i = 0; i < sNextStorageSlot; i++) { mStorage[i] = other.mStorage[i]; } @@ -144,7 +141,8 @@ public: void reset(const AccumulatorBuffer* other = NULL) { - for (size_t i = 0; i < mNextStorageSlot; i++) + llassert(mStorageSize >= sNextStorageSlot); + for (size_t i = 0; i < sNextStorageSlot; i++) { mStorage[i].reset(other ? &other->mStorage[i] : NULL); } @@ -172,7 +170,7 @@ public: { llerrs << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << llendl; } - size_t next_slot = mNextStorageSlot++; + size_t next_slot = sNextStorageSlot++; if (next_slot >= mStorageSize) { resize(mStorageSize + (mStorageSize >> 2)); @@ -208,7 +206,7 @@ public: size_t size() const { - return mNextStorageSlot; + return sNextStorageSlot; } static self_t* getDefaultBuffer() @@ -226,11 +224,15 @@ public: } private: - ACCUMULATOR* mStorage; - size_t mStorageSize; - size_t mNextStorageSlot; + ACCUMULATOR* mStorage; + size_t mStorageSize; + static size_t sNextStorageSlot; }; +template size_t AccumulatorBuffer::sNextStorageSlot = 0; + + + //TODO: replace with decltype when C++11 is enabled template struct MeanValueType -- cgit v1.2.3 From 49933aadb1b7044e947575bc377b34826e94fe99 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 11 Apr 2013 06:38:03 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics removed MeanValueType --- indra/llcommon/lltrace.h | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index a574be02da..376248c87a 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -231,15 +231,6 @@ private: template size_t AccumulatorBuffer::sNextStorageSlot = 0; - - -//TODO: replace with decltype when C++11 is enabled -template -struct MeanValueType -{ - typedef F64 type; -}; - template class TraceType : public LLInstanceTracker, std::string> @@ -382,6 +373,7 @@ private: U32 mNumSamples; }; + template class CountAccumulator { @@ -457,13 +449,6 @@ public: }; - -template<> -struct MeanValueType > -{ - typedef LLUnit type; -}; - template<> class TraceType : public TraceType @@ -475,13 +460,6 @@ public: {} }; -template<> -struct MeanValueType > -{ - typedef F64 type; -}; - - template<> class TraceType : public TraceType @@ -493,13 +471,6 @@ public: {} }; -template<> -struct MeanValueType > -{ - typedef LLUnit type; -}; - - class TimeBlock; class TimeBlockTreeNode { -- cgit v1.2.3 From 54d7fc95893d1bf8cc3b6ebe94f3bf37f40125d0 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 12 Apr 2013 14:25:40 -0700 Subject: BUILDFIX: attempted gcc fix --- indra/llcommon/lltrace.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 376248c87a..d1edaf969b 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -264,6 +264,7 @@ class MeasurementAccumulator { public: typedef T value_t; + typedef F64 mean_t; typedef MeasurementAccumulator self_t; MeasurementAccumulator() @@ -380,6 +381,7 @@ class CountAccumulator public: typedef CountAccumulator self_t; typedef T value_t; + typedef F64 mean_t; CountAccumulator() : mSum(0), @@ -418,17 +420,20 @@ class TimeBlockAccumulator { public: typedef LLUnit value_t; + typedef LLUnit mean_t; typedef TimeBlockAccumulator self_t; // fake class that allows us to view call count aspect of timeblock accumulator struct CallCountAspect { typedef U32 value_t; + typedef F32 mean_t; }; struct SelfTimeAspect { typedef LLUnit value_t; + typedef LLUnit mean_t; }; TimeBlockAccumulator(); -- cgit v1.2.3 From 9ae76d12157641033431381959ef4f798a119b8d Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 29 May 2013 17:00:50 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics fixed copy construction behavior of Recordings to not zero out data split measurement into event and sample, with sample representing a continuous function --- indra/llcommon/lltrace.h | 234 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 205 insertions(+), 29 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index d1edaf969b..f94576de45 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -73,7 +73,7 @@ bool isInitialized(); const LLThreadLocalPointer& get_thread_recorder(); void set_thread_recorder(class ThreadRecorder*); -class MasterThreadRecorder& getMasterThreadRecorder(); +class MasterThreadRecorder& getUIThreadRecorder(); // one per thread per type template @@ -148,6 +148,15 @@ public: } } + void flush() + { + llassert(mStorageSize >= sNextStorageSlot); + for (size_t i = 0; i < sNextStorageSlot; i++) + { + mStorage[i].flush(); + } + } + void makePrimary() { LLThreadLocalSingletonPointer::setInstance(mStorage); @@ -260,14 +269,14 @@ protected: }; template -class MeasurementAccumulator +class EventAccumulator { public: typedef T value_t; typedef F64 mean_t; - typedef MeasurementAccumulator self_t; + typedef EventAccumulator self_t; - MeasurementAccumulator() + EventAccumulator() : mSum(0), mMin((std::numeric_limits::max)()), mMax((std::numeric_limits::min)()), @@ -277,7 +286,7 @@ public: mLastValue(0) {} - void sample(T value) + void record(T value) { mNumSamples++; mSum += value; @@ -301,17 +310,10 @@ public: if (other.mNumSamples) { mSum += other.mSum; - if (other.mMin < mMin) - { - mMin = other.mMin; - } - if (other.mMax > mMax) - { - mMax = other.mMax; - } - F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples); - mNumSamples += other.mNumSamples; - mMean = mMean * weight + other.mMean * (1.f - weight); + + // 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 @@ -333,12 +335,16 @@ public: else { mVarianceSum = (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)); + * ((((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); mLastValue = other.mLastValue; } } @@ -347,13 +353,15 @@ public: { mNumSamples = 0; mSum = 0; - mMin = 0; - mMax = 0; + mMin = std::numeric_limits::max(); + mMax = std::numeric_limits::min(); mMean = 0; mVarianceSum = 0; mLastValue = other ? other->mLastValue : 0; } + void flush() {} + T getSum() const { return (T)mSum; } T getMin() const { return (T)mMin; } T getMax() const { return (T)mMax; } @@ -375,6 +383,150 @@ private: }; +template +class SampleAccumulator +{ +public: + typedef T value_t; + typedef F64 mean_t; + typedef SampleAccumulator self_t; + + SampleAccumulator() + : mSum(0), + mMin((std::numeric_limits::max)()), + mMax((std::numeric_limits::min)()), + mMean(0), + mVarianceSum(0), + mLastSampleTimeStamp(LLTimer::getTotalSeconds()), + mTotalSamplingTime(0), + mNumSamples(0), + mLastValue(0), + mHasValue(false) + {} + + void sample(T value) + { + LLUnitImplicit time_stamp = LLTimer::getTotalSeconds(); + LLUnitImplicit delta_time = time_stamp - mLastSampleTimeStamp; + mLastSampleTimeStamp = time_stamp; + + if (mHasValue) + { + mTotalSamplingTime += delta_time; + mSum += (F64)mLastValue * delta_time; + + // NOTE: both conditions will hold first time through + if (value < mMin) { mMin = value; } + if (value > mMax) { mMax = value; } + + F64 old_mean = mMean; + mMean += (delta_time / mTotalSamplingTime) * ((F64)mLastValue - old_mean); + mVarianceSum += delta_time * ((F64)mLastValue - old_mean) * ((F64)mLastValue - mMean); + } + + mLastValue = value; + mNumSamples++; + mHasValue = true; + } + + void addSamples(const self_t& other) + { + if (other.mTotalSamplingTime) + { + 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 = mTotalSamplingTime, + n_2 = other.mTotalSamplingTime; + F64 m_1 = mMean, + m_2 = other.mMean; + F64 v_1 = mVarianceSum / mTotalSamplingTime, + v_2 = other.mVarianceSum / other.mTotalSamplingTime; + if (n_1 == 0) + { + mVarianceSum = other.mVarianceSum; + } + else if (n_2 == 0) + { + // variance is unchanged + // mVarianceSum = mVarianceSum; + } + else + { + mVarianceSum = mTotalSamplingTime + * ((((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)); + } + + llassert(other.mTotalSamplingTime > 0); + F64 weight = mTotalSamplingTime / (mTotalSamplingTime + other.mTotalSamplingTime); + mNumSamples += other.mNumSamples; + mTotalSamplingTime += other.mTotalSamplingTime; + mMean = (mMean * weight) + (other.mMean * (1.0 - weight)); + mLastValue = other.mLastValue; + mLastSampleTimeStamp = other.mLastSampleTimeStamp; + mHasValue |= other.mHasValue; + } + } + + void reset(const self_t* other) + { + mNumSamples = 0; + mSum = 0; + mMin = std::numeric_limits::max(); + mMax = std::numeric_limits::min(); + mMean = other ? other->mLastValue : 0; + mVarianceSum = 0; + mLastSampleTimeStamp = LLTimer::getTotalSeconds(); + mTotalSamplingTime = 0; + mLastValue = other ? other->mLastValue : 0; + mHasValue = other ? other->mHasValue : false; + } + + void flush() + { + LLUnitImplicit time_stamp = LLTimer::getTotalSeconds(); + LLUnitImplicit delta_time = time_stamp - mLastSampleTimeStamp; + + mSum += (F64)mLastValue * delta_time; + + mTotalSamplingTime += delta_time; + mLastSampleTimeStamp = time_stamp; + } + + 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 / mTotalSamplingTime); } + U32 getSampleCount() const { return mNumSamples; } + +private: + T mSum, + mMin, + mMax, + mLastValue; + + bool mHasValue; + + F64 mMean, + mVarianceSum; + + LLUnitImplicit mLastSampleTimeStamp, + mTotalSamplingTime; + + U32 mNumSamples; +}; + template class CountAccumulator { @@ -406,6 +558,8 @@ public: mSum = 0; } + void flush() {} + T getSum() const { return (T)mSum; } U32 getSampleCount() const { return mNumSamples; } @@ -439,6 +593,7 @@ public: TimeBlockAccumulator(); void addSamples(const self_t& other); void reset(const self_t* other); + void flush() {} // // members @@ -493,25 +648,44 @@ public: template -class MeasurementStatHandle -: public TraceType::type_t> > +class EventStatHandle +: public TraceType::type_t> > { public: typedef typename LLUnits::HighestPrecisionType::type_t storage_t; - typedef TraceType::type_t> > trace_t; + typedef TraceType::type_t> > trace_t; - MeasurementStatHandle(const char* name, const char* description = NULL) + EventStatHandle(const char* name, const char* description = NULL) : trace_t(name, description) {} }; template -void sample(MeasurementStatHandle& measurement, VALUE_T value) +void record(EventStatHandle& measurement, VALUE_T value) { T converted_value(value); - measurement.getPrimaryAccumulator()->sample(LLUnits::rawValue(converted_value)); + measurement.getPrimaryAccumulator()->record(LLUnits::rawValue(converted_value)); } +template +class SampleStatHandle +: public TraceType::type_t> > +{ +public: + typedef typename LLUnits::HighestPrecisionType::type_t storage_t; + typedef TraceType::type_t> > trace_t; + + SampleStatHandle(const char* name, const char* description = NULL) + : trace_t(name, description) + {} +}; + +template +void sample(SampleStatHandle& measurement, VALUE_T value) +{ + T converted_value(value); + measurement.getPrimaryAccumulator()->sample(LLUnits::rawValue(converted_value)); +} template class CountStatHandle @@ -560,6 +734,8 @@ struct MemStatAccumulator mDeallocatedCount = 0; } + void flush() {} + size_t mSize, mChildSize; int mAllocatedCount, -- cgit v1.2.3 From 074c1f1de45f60059c97cf9cfd0bbb9fddbb52c4 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 29 May 2013 17:02:27 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics made LLCopyOnWritePointer enforce write access through write() again disabled some error checking on release for download builds --- indra/llcommon/lltrace.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index f94576de45..e950a119d3 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -175,10 +175,12 @@ public: // NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned size_t reserveSlot() { +#ifndef LL_RELEASE_FOR_DOWNLOAD if (LLTrace::isInitialized()) { llerrs << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << llendl; } +#endif size_t next_slot = sNextStorageSlot++; if (next_slot >= mStorageSize) { -- cgit v1.2.3 From ae355188327515d53b9c15c27ed576829fce3668 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 30 May 2013 18:30:11 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics fixed LLTrace::ExtendablePeriodicRecording::extend() to include *all* frame extensions gated SlaveThreadRecorder pushing to master based on master update rate reverted changes to LLThreadLocalSingletonPointer to not use offset-from-default trick --- indra/llcommon/lltrace.h | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index e950a119d3..00bab536ff 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -35,6 +35,7 @@ #include "llunit.h" #include "llapr.h" #include "llthreadlocalstorage.h" +#include "lltimer.h" #include @@ -75,7 +76,6 @@ void set_thread_recorder(class ThreadRecorder*); class MasterThreadRecorder& getUIThreadRecorder(); -// one per thread per type template class AccumulatorBuffer : public LLRefCount { @@ -104,9 +104,9 @@ public: ~AccumulatorBuffer() { - if (LLThreadLocalSingletonPointer::getInstance() == mStorage) + if (isPrimary()) { - LLThreadLocalSingletonPointer::setInstance(getDefaultBuffer()->mStorage); + LLThreadLocalSingletonPointer::setInstance(NULL); } delete[] mStorage; } @@ -169,7 +169,8 @@ public: LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage() { - return LLThreadLocalSingletonPointer::getInstance(); + ACCUMULATOR* accumulator = LLThreadLocalSingletonPointer::getInstance(); + return accumulator ? accumulator : sDefaultBuffer->mStorage; } // NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned @@ -222,25 +223,27 @@ public: static self_t* getDefaultBuffer() { - // this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data - // so as not to trigger an access violation - static self_t* sBuffer = new AccumulatorBuffer(StaticAllocationMarker()); static bool sInitialized = false; if (!sInitialized) { - sBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE); + // this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data + // so as not to trigger an access violation + sDefaultBuffer = new AccumulatorBuffer(StaticAllocationMarker()); sInitialized = true; + sDefaultBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE); } - return sBuffer; + return sDefaultBuffer; } private: ACCUMULATOR* mStorage; size_t mStorageSize; static size_t sNextStorageSlot; + static self_t* sDefaultBuffer; }; template size_t AccumulatorBuffer::sNextStorageSlot = 0; +template AccumulatorBuffer* AccumulatorBuffer::sDefaultBuffer = NULL; template class TraceType -- cgit v1.2.3 From e50e6004082223fdc0bfd78bc697d48a7f45b379 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 30 May 2013 20:15:48 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics reverted SlaveThreadRecorder update gating moved processTimes() outside of Recording, so it is called only once per frame refined sample merge logic so that multi-threaded samples do not stomp on linear history of a stat --- indra/llcommon/lltrace.h | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 00bab536ff..6dfe9e4b4e 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -121,12 +121,12 @@ public: return mStorage[index]; } - void addSamples(const AccumulatorBuffer& other) + void addSamples(const AccumulatorBuffer& other, bool append = true) { llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize > sNextStorageSlot); for (size_t i = 0; i < sNextStorageSlot; i++) { - mStorage[i].addSamples(other.mStorage[i]); + mStorage[i].addSamples(other.mStorage[i], append); } } @@ -310,7 +310,7 @@ public: mLastValue = value; } - void addSamples(const self_t& other) + void addSamples(const self_t& other, bool append) { if (other.mNumSamples) { @@ -350,7 +350,7 @@ public: F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples); mNumSamples += other.mNumSamples; mMean = mMean * weight + other.mMean * (1.f - weight); - mLastValue = other.mLastValue; + if (append) mLastValue = other.mLastValue; } } @@ -434,7 +434,7 @@ public: mHasValue = true; } - void addSamples(const self_t& other) + void addSamples(const self_t& other, bool append) { if (other.mTotalSamplingTime) { @@ -476,9 +476,12 @@ public: mNumSamples += other.mNumSamples; mTotalSamplingTime += other.mTotalSamplingTime; mMean = (mMean * weight) + (other.mMean * (1.0 - weight)); - mLastValue = other.mLastValue; - mLastSampleTimeStamp = other.mLastSampleTimeStamp; - mHasValue |= other.mHasValue; + if (append) + { + mLastValue = other.mLastValue; + mLastSampleTimeStamp = other.mLastSampleTimeStamp; + mHasValue |= other.mHasValue; + } } } @@ -551,7 +554,7 @@ public: mSum += value; } - void addSamples(const CountAccumulator& other) + void addSamples(const CountAccumulator& other, bool /*append*/) { mSum += other.mSum; mNumSamples += other.mNumSamples; @@ -596,7 +599,7 @@ public: }; TimeBlockAccumulator(); - void addSamples(const self_t& other); + void addSamples(const self_t& other, bool /*append*/); void reset(const self_t* other); void flush() {} @@ -716,6 +719,8 @@ void add(CountStatHandle& count, VALUE_T value) struct MemStatAccumulator { + typedef MemStatAccumulator self_t; + MemStatAccumulator() : mSize(0), mChildSize(0), @@ -723,7 +728,7 @@ struct MemStatAccumulator mDeallocatedCount(0) {} - void addSamples(const MemStatAccumulator& other) + void addSamples(const MemStatAccumulator& other, bool /*append*/) { mSize += other.mSize; mChildSize += other.mChildSize; -- cgit v1.2.3 From 9def3590f41dee3cba7760e4443fdc71f5fb2db6 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 31 May 2013 16:01:46 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics fixed multithreading lltrace causing values to be interpolated towards 0 added Radians unit improved sceneloadmonitor restart heuristic to use accumulated camera motion --- indra/llcommon/lltrace.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 6dfe9e4b4e..0daac95ea4 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -504,9 +504,11 @@ public: LLUnitImplicit time_stamp = LLTimer::getTotalSeconds(); LLUnitImplicit delta_time = time_stamp - mLastSampleTimeStamp; - mSum += (F64)mLastValue * delta_time; - - mTotalSamplingTime += delta_time; + if (mHasValue) + { + mSum += (F64)mLastValue * delta_time; + mTotalSamplingTime += delta_time; + } mLastSampleTimeStamp = time_stamp; } -- cgit v1.2.3 From 233201f8227f92e93061d3e2393a17b42dfa3dd1 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sun, 2 Jun 2013 22:49:17 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics removed unnecessary templates from accumulator types...now always track data in double precision floating point, using templated accessors to convert to and from arbitrary types --- indra/llcommon/lltrace.h | 96 +++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 51 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 0daac95ea4..d6b51a63ee 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -273,25 +273,23 @@ protected: const size_t mAccumulatorIndex; }; -template class EventAccumulator { public: - typedef T value_t; + typedef F64 value_t; typedef F64 mean_t; - typedef EventAccumulator self_t; EventAccumulator() : mSum(0), - mMin((std::numeric_limits::max)()), - mMax((std::numeric_limits::min)()), + mMin((std::numeric_limits::max)()), + mMax((std::numeric_limits::min)()), mMean(0), mVarianceSum(0), mNumSamples(0), mLastValue(0) {} - void record(T value) + void record(F64 value) { mNumSamples++; mSum += value; @@ -305,12 +303,12 @@ public: mMax = value; } F64 old_mean = mMean; - mMean += ((F64)value - old_mean) / (F64)mNumSamples; - mVarianceSum += ((F64)value - old_mean) * ((F64)value - mMean); + mMean += (value - old_mean) / (F64)mNumSamples; + mVarianceSum += (value - old_mean) * (value - mMean); mLastValue = value; } - void addSamples(const self_t& other, bool append) + void addSamples(const EventAccumulator& other, bool append) { if (other.mNumSamples) { @@ -354,12 +352,12 @@ public: } } - void reset(const self_t* other) + void reset(const EventAccumulator* other) { mNumSamples = 0; mSum = 0; - mMin = std::numeric_limits::max(); - mMax = std::numeric_limits::min(); + mMin = std::numeric_limits::max(); + mMax = std::numeric_limits::min(); mMean = 0; mVarianceSum = 0; mLastValue = other ? other->mLastValue : 0; @@ -367,16 +365,16 @@ public: void flush() {} - 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 getSum() const { return mSum; } + F64 getMin() const { return mMin; } + F64 getMax() const { return mMax; } + F64 getLastValue() const { return mLastValue; } F64 getMean() const { return mMean; } F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mNumSamples); } U32 getSampleCount() const { return mNumSamples; } private: - T mSum, + F64 mSum, mMin, mMax, mLastValue; @@ -388,18 +386,16 @@ private: }; -template class SampleAccumulator { public: - typedef T value_t; + typedef F64 value_t; typedef F64 mean_t; - typedef SampleAccumulator self_t; SampleAccumulator() : mSum(0), - mMin((std::numeric_limits::max)()), - mMax((std::numeric_limits::min)()), + mMin((std::numeric_limits::max)()), + mMax((std::numeric_limits::min)()), mMean(0), mVarianceSum(0), mLastSampleTimeStamp(LLTimer::getTotalSeconds()), @@ -409,7 +405,7 @@ public: mHasValue(false) {} - void sample(T value) + void sample(F64 value) { LLUnitImplicit time_stamp = LLTimer::getTotalSeconds(); LLUnitImplicit delta_time = time_stamp - mLastSampleTimeStamp; @@ -418,15 +414,15 @@ public: if (mHasValue) { mTotalSamplingTime += delta_time; - mSum += (F64)mLastValue * delta_time; + mSum += mLastValue * delta_time; // NOTE: both conditions will hold first time through if (value < mMin) { mMin = value; } if (value > mMax) { mMax = value; } F64 old_mean = mMean; - mMean += (delta_time / mTotalSamplingTime) * ((F64)mLastValue - old_mean); - mVarianceSum += delta_time * ((F64)mLastValue - old_mean) * ((F64)mLastValue - mMean); + mMean += (delta_time / mTotalSamplingTime) * (mLastValue - old_mean); + mVarianceSum += delta_time * (mLastValue - old_mean) * (mLastValue - mMean); } mLastValue = value; @@ -434,7 +430,7 @@ public: mHasValue = true; } - void addSamples(const self_t& other, bool append) + void addSamples(const SampleAccumulator& other, bool append) { if (other.mTotalSamplingTime) { @@ -485,12 +481,12 @@ public: } } - void reset(const self_t* other) + void reset(const SampleAccumulator* other) { mNumSamples = 0; mSum = 0; - mMin = std::numeric_limits::max(); - mMax = std::numeric_limits::min(); + mMin = std::numeric_limits::max(); + mMax = std::numeric_limits::min(); mMean = other ? other->mLastValue : 0; mVarianceSum = 0; mLastSampleTimeStamp = LLTimer::getTotalSeconds(); @@ -506,22 +502,22 @@ public: if (mHasValue) { - mSum += (F64)mLastValue * delta_time; + mSum += mLastValue * delta_time; mTotalSamplingTime += delta_time; } mLastSampleTimeStamp = time_stamp; } - 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 getSum() const { return mSum; } + F64 getMin() const { return mMin; } + F64 getMax() const { return mMax; } + F64 getLastValue() const { return mLastValue; } F64 getMean() const { return mMean; } F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mTotalSamplingTime); } U32 getSampleCount() const { return mNumSamples; } private: - T mSum, + F64 mSum, mMin, mMax, mLastValue; @@ -537,12 +533,10 @@ private: U32 mNumSamples; }; -template class CountAccumulator { public: - typedef CountAccumulator self_t; - typedef T value_t; + typedef F64 value_t; typedef F64 mean_t; CountAccumulator() @@ -550,19 +544,19 @@ public: mNumSamples(0) {} - void add(T value) + void add(F64 value) { mNumSamples++; mSum += value; } - void addSamples(const CountAccumulator& other, bool /*append*/) + void addSamples(const CountAccumulator& other, bool /*append*/) { mSum += other.mSum; mNumSamples += other.mNumSamples; } - void reset(const self_t* other) + void reset(const CountAccumulator* other) { mNumSamples = 0; mSum = 0; @@ -570,12 +564,12 @@ public: void flush() {} - T getSum() const { return (T)mSum; } + F64 getSum() const { return mSum; } U32 getSampleCount() const { return mNumSamples; } private: - T mSum; + F64 mSum; U32 mNumSamples; }; @@ -659,11 +653,11 @@ public: template class EventStatHandle -: public TraceType::type_t> > +: public TraceType { public: typedef typename LLUnits::HighestPrecisionType::type_t storage_t; - typedef TraceType::type_t> > trace_t; + typedef TraceType trace_t; EventStatHandle(const char* name, const char* description = NULL) : trace_t(name, description) @@ -679,11 +673,11 @@ void record(EventStatHandle& measurement, VALUE_T value) template class SampleStatHandle -: public TraceType::type_t> > +: public TraceType { public: - typedef typename LLUnits::HighestPrecisionType::type_t storage_t; - typedef TraceType::type_t> > trace_t; + typedef F64 storage_t; + typedef TraceType trace_t; SampleStatHandle(const char* name, const char* description = NULL) : trace_t(name, description) @@ -699,11 +693,11 @@ void sample(SampleStatHandle& measurement, VALUE_T value) template class CountStatHandle -: public TraceType::type_t> > +: public TraceType { public: typedef typename LLUnits::HighestPrecisionType::type_t storage_t; - typedef TraceType::type_t> > trace_t; + typedef TraceType trace_t; CountStatHandle(const char* name, const char* description = NULL) : trace_t(name) -- cgit v1.2.3 From 5b48107dbf969529267874bff9a0a4b892b348cf Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 4 Jun 2013 08:33:11 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics added labels to LLUnit types added memstat dumps to llscenemonitor --- indra/llcommon/lltrace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index d6b51a63ee..c485552061 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -656,7 +656,7 @@ class EventStatHandle : public TraceType { public: - typedef typename LLUnits::HighestPrecisionType::type_t storage_t; + typedef typename F64 storage_t; typedef TraceType trace_t; EventStatHandle(const char* name, const char* description = NULL) @@ -696,7 +696,7 @@ class CountStatHandle : public TraceType { public: - typedef typename LLUnits::HighestPrecisionType::type_t storage_t; + typedef typename F64 storage_t; typedef TraceType trace_t; CountStatHandle(const char* name, const char* description = NULL) -- cgit v1.2.3 From 715385eed7b2276963015861d7e6b8196e6ae5cd Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 4 Jun 2013 10:54:12 -0700 Subject: BUILDFIX: don't multiple define class statics...use inline static method instead --- indra/llcommon/lltrace.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index c485552061..2953e993d4 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -265,6 +265,8 @@ public: size_t getIndex() const { return mAccumulatorIndex; } + virtual const char* getUnitLabel() { return ""; } + const std::string& getName() const { return mName; } protected: @@ -662,6 +664,9 @@ public: EventStatHandle(const char* name, const char* description = NULL) : trace_t(name, description) {} + + /*virtual*/ const char* getUnitLabel() { return LLGetUnitLabel::getUnitLabel(); } + }; template @@ -682,6 +687,8 @@ public: SampleStatHandle(const char* name, const char* description = NULL) : trace_t(name, description) {} + + /*virtual*/ const char* getUnitLabel() { return LLGetUnitLabel::getUnitLabel(); } }; template @@ -703,6 +710,7 @@ public: : trace_t(name) {} + /*virtual*/ const char* getUnitLabel() { return LLGetUnitLabel::getUnitLabel(); } }; template @@ -755,6 +763,8 @@ public: MemStatHandle(const char* name) : trace_t(name) {} + + /*virtual*/ const char* getUnitLabel() { return "B"; } }; // measures effective memory footprint of specified type -- cgit v1.2.3 From a74b5dfa923f8eeccc9b786143f0f832de3ad450 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 4 Jun 2013 19:45:33 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics fixed mem stat tracking...now properly tracks memory footprint with floating point precision cleaned up macros for unit declaration renamed units to SI standard for 1024 multiples (kibibytes, etc) fixed units output for scene monitor dump --- indra/llcommon/lltrace.h | 143 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 106 insertions(+), 37 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 2953e993d4..37196d9f63 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -46,13 +46,13 @@ namespace LLTrace class Recording; typedef LLUnit Bytes; -typedef LLUnit Kilobytes; -typedef LLUnit Megabytes; -typedef LLUnit Gigabytes; +typedef LLUnit Kibibytes; +typedef LLUnit Mibibytes; +typedef LLUnit Gibibytes; typedef LLUnit Bits; -typedef LLUnit Kilobits; -typedef LLUnit Megabits; -typedef LLUnit Gigabits; +typedef LLUnit Kibibits; +typedef LLUnit Mibibits; +typedef LLUnit Gibibits; typedef LLUnit Seconds; typedef LLUnit Milliseconds; @@ -583,14 +583,14 @@ public: typedef LLUnit mean_t; typedef TimeBlockAccumulator self_t; - // fake class that allows us to view call count aspect of timeblock accumulator - struct CallCountAspect + // fake classes that allows us to view different facets of underlying statistic + struct CallCountFacet { typedef U32 value_t; typedef F32 mean_t; }; - struct SelfTimeAspect + struct SelfTimeFacet { typedef LLUnit value_t; typedef LLUnit mean_t; @@ -616,7 +616,7 @@ public: }; template<> -class TraceType +class TraceType : public TraceType { public: @@ -627,7 +627,7 @@ public: }; template<> -class TraceType +class TraceType : public TraceType { public: @@ -725,35 +725,90 @@ struct MemStatAccumulator { typedef MemStatAccumulator self_t; + // fake classes that allows us to view different facets of underlying statistic + struct AllocationCountFacet + { + typedef U32 value_t; + typedef F32 mean_t; + }; + + struct DeallocationCountFacet + { + typedef U32 value_t; + typedef F32 mean_t; + }; + + struct ChildMemFacet + { + typedef LLUnit value_t; + typedef LLUnit mean_t; + }; + MemStatAccumulator() - : mSize(0), - mChildSize(0), - mAllocatedCount(0), + : mAllocatedCount(0), mDeallocatedCount(0) {} - void addSamples(const MemStatAccumulator& other, bool /*append*/) + void addSamples(const MemStatAccumulator& other, bool append) { - mSize += other.mSize; - mChildSize += other.mChildSize; + mSize.addSamples(other.mSize, append); + mChildSize.addSamples(other.mChildSize, append); mAllocatedCount += other.mAllocatedCount; mDeallocatedCount += other.mDeallocatedCount; } void reset(const MemStatAccumulator* other) { - mSize = 0; - mChildSize = 0; + mSize.reset(other ? &other->mSize : NULL); + mChildSize.reset(other ? &other->mChildSize : NULL); mAllocatedCount = 0; mDeallocatedCount = 0; } - void flush() {} + void flush() + { + mSize.flush(); + mChildSize.flush(); + } + + SampleAccumulator mSize, + mChildSize; + int mAllocatedCount, + mDeallocatedCount; +}; + + +template<> +class TraceType +: public TraceType +{ +public: + + TraceType(const char* name, const char* description = "") + : TraceType(name, description) + {} +}; - size_t mSize, - mChildSize; - int mAllocatedCount, - mDeallocatedCount; +template<> +class TraceType +: public TraceType +{ +public: + + TraceType(const char* name, const char* description = "") + : TraceType(name, description) + {} +}; + +template<> +class TraceType + : public TraceType +{ +public: + + TraceType(const char* name, const char* description = "") + : TraceType(name, description) + {} }; class MemStatHandle : public TraceType @@ -765,6 +820,21 @@ public: {} /*virtual*/ const char* getUnitLabel() { return "B"; } + + TraceType& allocationCount() + { + return static_cast&>(*(TraceType*)this); + } + + TraceType& deallocationCount() + { + return static_cast&>(*(TraceType*)this); + } + + TraceType& childMem() + { + return static_cast&>(*(TraceType*)this); + } }; // measures effective memory footprint of specified type @@ -865,7 +935,7 @@ public: MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { - accumulator->mSize += size; + accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size); accumulator->mAllocatedCount++; } @@ -877,7 +947,7 @@ public: MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { - accumulator->mSize -= size; + accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size); accumulator->mAllocatedCount--; accumulator->mDeallocatedCount++; } @@ -889,7 +959,7 @@ public: MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { - accumulator->mSize += size; + accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size); accumulator->mAllocatedCount++; } @@ -901,7 +971,7 @@ public: MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { - accumulator->mSize -= size; + accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size); accumulator->mAllocatedCount--; accumulator->mDeallocatedCount++; } @@ -924,13 +994,13 @@ public: } - void memClaim(size_t size) + void memClaimAmount(size_t size) { MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); mMemFootprint += size; if (accumulator) { - accumulator->mSize += size; + accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size); } } @@ -949,14 +1019,13 @@ public: return value; } - void memDisclaim(size_t size) + void memDisclaimAmount(size_t size) { MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { - accumulator->mSize -= size; + accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size); } - mMemFootprint -= size; } private: @@ -971,7 +1040,7 @@ private: if (accumulator) { size_t footprint = MemFootprint::measure(tracked); - accumulator->mSize += footprint; + accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)footprint); tracker.mMemFootprint += footprint; } } @@ -982,7 +1051,7 @@ private: if (accumulator) { size_t footprint = MemFootprint::measure(tracked); - accumulator->mSize -= footprint; + accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)footprint); tracker.mMemFootprint -= footprint; } } @@ -996,7 +1065,7 @@ private: MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { - accumulator->mChildSize += MemFootprint::measure(tracked); + accumulator->mChildSize.sample(accumulator->mChildSize.getLastValue() + (F64)MemFootprint::measure(tracked)); } } @@ -1005,7 +1074,7 @@ private: MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { - accumulator->mChildSize -= MemFootprint::measure(tracked); + accumulator->mChildSize.sample(accumulator->mChildSize.getLastValue() - (F64)MemFootprint::measure(tracked)); } } }; -- cgit v1.2.3 From 60b625588faec2472597dae50331b2ce95ce40a2 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 5 Jun 2013 19:57:07 -0700 Subject: BUILDFIX: build fixes for mac --- indra/llcommon/lltrace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 343e1b16e8..c20e836f77 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -657,7 +657,7 @@ class EventStatHandle : public TraceType { public: - typedef typename F64 storage_t; + typedef F64 storage_t; typedef TraceType trace_t; EventStatHandle(const char* name, const char* description = NULL) @@ -702,7 +702,7 @@ class CountStatHandle : public TraceType { public: - typedef typename F64 storage_t; + typedef F64 storage_t; typedef TraceType trace_t; CountStatHandle(const char* name, const char* description = NULL) -- cgit v1.2.3 From ebf35d51b14f224c36a19a453a20885e667f6bec Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 6 Jun 2013 21:26:57 -0700 Subject: SH-4232 FIX: Interesting: Viewer Crash on Login --- indra/llcommon/lltrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index c20e836f77..cfe1273b4b 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -169,7 +169,7 @@ public: LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage() { ACCUMULATOR* accumulator = LLThreadLocalSingletonPointer::getInstance(); - return accumulator ? accumulator : sDefaultBuffer->mStorage; + return accumulator ? accumulator : getDefaultBuffer()->mStorage; } // NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned -- cgit v1.2.3 From 9fd3af3c389ed491b515cbb5136b344b069913e4 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 13 Jun 2013 15:29:15 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics changed Units macros and argument order to make it more clear optimized units for integer types fixed merging of periodicrecordings...should eliminate duplicate entries in sceneloadmonitor history --- indra/llcommon/lltrace.h | 76 ++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 35 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index cfe1273b4b..1bf853c5c0 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -44,27 +44,27 @@ namespace LLTrace { class Recording; -typedef LLUnit Bytes; -typedef LLUnit Kibibytes; -typedef LLUnit Mibibytes; -typedef LLUnit Gibibytes; -typedef LLUnit Bits; -typedef LLUnit Kibibits; -typedef LLUnit Mibibits; -typedef LLUnit Gibibits; - -typedef LLUnit Seconds; -typedef LLUnit Milliseconds; -typedef LLUnit Minutes; -typedef LLUnit Hours; -typedef LLUnit Milliseconds; -typedef LLUnit Microseconds; -typedef LLUnit Nanoseconds; - -typedef LLUnit Meters; -typedef LLUnit Kilometers; -typedef LLUnit Centimeters; -typedef LLUnit Millimeters; +typedef LLUnit Bytes; +typedef LLUnit Kibibytes; +typedef LLUnit Mibibytes; +typedef LLUnit Gibibytes; +typedef LLUnit Bits; +typedef LLUnit Kibibits; +typedef LLUnit Mibibits; +typedef LLUnit Gibibits; + +typedef LLUnit Seconds; +typedef LLUnit Milliseconds; +typedef LLUnit Minutes; +typedef LLUnit Hours; +typedef LLUnit Milliseconds; +typedef LLUnit Microseconds; +typedef LLUnit Nanoseconds; + +typedef LLUnit Meters; +typedef LLUnit Kilometers; +typedef LLUnit Centimeters; +typedef LLUnit Millimeters; void init(); void cleanup(); @@ -216,6 +216,11 @@ public: } size_t size() const + { + return getNumIndices(); + } + + static size_t getNumIndices() { return sNextStorageSlot; } @@ -263,6 +268,7 @@ public: } size_t getIndex() const { return mAccumulatorIndex; } + static size_t getNumIndices() { return AccumulatorBuffer::getNumIndices(); } virtual const char* getUnitLabel() { return ""; } @@ -408,8 +414,8 @@ public: void sample(F64 value) { - LLUnitImplicit time_stamp = LLTimer::getTotalSeconds(); - LLUnitImplicit delta_time = time_stamp - mLastSampleTimeStamp; + LLUnitImplicit time_stamp = LLTimer::getTotalSeconds(); + LLUnitImplicit delta_time = time_stamp - mLastSampleTimeStamp; mLastSampleTimeStamp = time_stamp; if (mHasValue) @@ -498,8 +504,8 @@ public: void flush() { - LLUnitImplicit time_stamp = LLTimer::getTotalSeconds(); - LLUnitImplicit delta_time = time_stamp - mLastSampleTimeStamp; + LLUnitImplicit time_stamp = LLTimer::getTotalSeconds(); + LLUnitImplicit delta_time = time_stamp - mLastSampleTimeStamp; if (mHasValue) { @@ -528,7 +534,7 @@ private: F64 mMean, mVarianceSum; - LLUnitImplicit mLastSampleTimeStamp, + LLUnitImplicit mLastSampleTimeStamp, mTotalSamplingTime; U32 mNumSamples; @@ -578,8 +584,8 @@ private: class TimeBlockAccumulator { public: - typedef LLUnit value_t; - typedef LLUnit mean_t; + typedef LLUnit value_t; + typedef LLUnit mean_t; typedef TimeBlockAccumulator self_t; // fake classes that allows us to view different facets of underlying statistic @@ -591,8 +597,8 @@ public: struct SelfTimeFacet { - typedef LLUnit value_t; - typedef LLUnit mean_t; + typedef LLUnit value_t; + typedef LLUnit mean_t; }; TimeBlockAccumulator(); @@ -672,7 +678,7 @@ template void record(EventStatHandle& measurement, VALUE_T value) { T converted_value(value); - measurement.getPrimaryAccumulator()->record(LLUnits::rawValue(converted_value)); + measurement.getPrimaryAccumulator()->record(LLUnits::storageValue(converted_value)); } template @@ -694,7 +700,7 @@ template void sample(SampleStatHandle& measurement, VALUE_T value) { T converted_value(value); - measurement.getPrimaryAccumulator()->sample(LLUnits::rawValue(converted_value)); + measurement.getPrimaryAccumulator()->sample(LLUnits::storageValue(converted_value)); } template @@ -716,7 +722,7 @@ template void add(CountStatHandle& count, VALUE_T value) { T converted_value(value); - count.getPrimaryAccumulator()->add(LLUnits::rawValue(converted_value)); + count.getPrimaryAccumulator()->add(LLUnits::storageValue(converted_value)); } @@ -739,8 +745,8 @@ struct MemStatAccumulator struct ChildMemFacet { - typedef LLUnit value_t; - typedef LLUnit mean_t; + typedef LLUnit value_t; + typedef LLUnit mean_t; }; MemStatAccumulator() -- cgit v1.2.3 From 3f2de87340b1c831ea59e4a3ca960d49f343c9fd Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 17 Jun 2013 01:18:21 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics added getAs and setAs to LLUnit to make it clearer how you specify units removed accidental 0-based indexing of periodicRecording history... should now be consistently 1-based, with 0 accessing current active recording removed per frame timer updates of all historical timer bars in fast timer display added missing assignment operator to recordings --- indra/llcommon/lltrace.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 1bf853c5c0..cd377531e8 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -66,6 +66,16 @@ typedef LLUnit Kilometers; typedef LLUnit Centimeters; typedef LLUnit Millimeters; + +template +T storage_value(T val) { return val; } + +template +STORAGE_TYPE storage_value(LLUnit val) { return val.value(); } + +template +STORAGE_TYPE storage_value(LLUnitImplicit val) { return val.value(); } + void init(); void cleanup(); bool isInitialized(); @@ -678,7 +688,7 @@ template void record(EventStatHandle& measurement, VALUE_T value) { T converted_value(value); - measurement.getPrimaryAccumulator()->record(LLUnits::storageValue(converted_value)); + measurement.getPrimaryAccumulator()->record(storage_value(converted_value)); } template @@ -700,7 +710,7 @@ template void sample(SampleStatHandle& measurement, VALUE_T value) { T converted_value(value); - measurement.getPrimaryAccumulator()->sample(LLUnits::storageValue(converted_value)); + measurement.getPrimaryAccumulator()->sample(storage_value(converted_value)); } template @@ -722,7 +732,7 @@ template void add(CountStatHandle& count, VALUE_T value) { T converted_value(value); - count.getPrimaryAccumulator()->add(LLUnits::storageValue(converted_value)); + count.getPrimaryAccumulator()->add(storage_value(converted_value)); } -- cgit v1.2.3 From d136c4c29686c565b5a46503aa67a9c958b4145d Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 18 Jun 2013 23:41:53 -0700 Subject: SH-4246 FIX interesting: fast timers significantly decreases framerate removed implicit flushes on reads from recorders for better performance made sure stack timers were updated on recorder deactivate faster rendering and better ui for fast timer view --- indra/llcommon/lltrace.h | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index cd377531e8..6292534a03 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -157,12 +157,12 @@ public: } } - void flush() + void flush(LLUnitImplicit time_stamp) { llassert(mStorageSize >= sNextStorageSlot); for (size_t i = 0; i < sNextStorageSlot; i++) { - mStorage[i].flush(); + mStorage[i].flush(time_stamp); } } @@ -380,7 +380,7 @@ public: mLastValue = other ? other->mLastValue : 0; } - void flush() {} + void flush(LLUnitImplicit) {} F64 getSum() const { return mSum; } F64 getMin() const { return mMin; } @@ -512,9 +512,8 @@ public: mHasValue = other ? other->mHasValue : false; } - void flush() + void flush(LLUnitImplicit time_stamp) { - LLUnitImplicit time_stamp = LLTimer::getTotalSeconds(); LLUnitImplicit delta_time = time_stamp - mLastSampleTimeStamp; if (mHasValue) @@ -579,7 +578,7 @@ public: mSum = 0; } - void flush() {} + void flush(LLUnitImplicit) {} F64 getSum() const { return mSum; } @@ -614,7 +613,7 @@ public: TimeBlockAccumulator(); void addSamples(const self_t& other, bool /*append*/); void reset(const self_t* other); - void flush() {} + void flush(LLUnitImplicit) {} // // members @@ -780,10 +779,10 @@ struct MemStatAccumulator mDeallocatedCount = 0; } - void flush() + void flush(LLUnitImplicit time_stamp) { - mSize.flush(); - mChildSize.flush(); + mSize.flush(time_stamp); + mChildSize.flush(time_stamp); } SampleAccumulator mSize, -- cgit v1.2.3 From c5fc8f90060aa7a6c8fbb72313172423b01eddc5 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 19 Jun 2013 08:23:53 -0700 Subject: SH-4246 FIX interesting: fast timers significantly decreases framerate moved collapsed flag to fast timer tree node --- indra/llcommon/lltrace.h | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 6292534a03..fb7ffb0a29 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -663,6 +663,7 @@ public: TimeBlock* mBlock; TimeBlock* mParent; std::vector mChildren; + bool mCollapsed; bool mNeedsSorting; }; -- cgit v1.2.3 From fe3cfb30d504155850ddf3752d2f55e6311990d6 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sat, 22 Jun 2013 00:34:25 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics removed LLTrace unit typedefs --- indra/llcommon/lltrace.h | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index fb7ffb0a29..884a316a3b 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -44,29 +44,6 @@ namespace LLTrace { class Recording; -typedef LLUnit Bytes; -typedef LLUnit Kibibytes; -typedef LLUnit Mibibytes; -typedef LLUnit Gibibytes; -typedef LLUnit Bits; -typedef LLUnit Kibibits; -typedef LLUnit Mibibits; -typedef LLUnit Gibibits; - -typedef LLUnit Seconds; -typedef LLUnit Milliseconds; -typedef LLUnit Minutes; -typedef LLUnit Hours; -typedef LLUnit Milliseconds; -typedef LLUnit Microseconds; -typedef LLUnit Nanoseconds; - -typedef LLUnit Meters; -typedef LLUnit Kilometers; -typedef LLUnit Centimeters; -typedef LLUnit Millimeters; - - template T storage_value(T val) { return val; } -- cgit v1.2.3 From 8bddaeec6647e735415f9bd72a4e1313e11fe720 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sat, 22 Jun 2013 12:00:18 -0700 Subject: fixed scene load monitor resetting to eagerly due to spurious camer amotion pulled swap() out of ui time block cleaned up internal lltrace dependencies, factored out common accumulator definitions --- indra/llcommon/lltrace.h | 594 +---------------------------------------------- 1 file changed, 1 insertion(+), 593 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index fb7ffb0a29..36a3eb8fe8 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -32,7 +32,7 @@ #include "llmemory.h" #include "llrefcount.h" -#include "llunit.h" +#include "lltraceaccumulators.h" #include "llthreadlocalstorage.h" #include "lltimer.h" @@ -80,185 +80,6 @@ void init(); void cleanup(); bool isInitialized(); -const LLThreadLocalPointer& get_thread_recorder(); -void set_thread_recorder(class ThreadRecorder*); - -class MasterThreadRecorder& getUIThreadRecorder(); - -template -class AccumulatorBuffer : public LLRefCount -{ - typedef AccumulatorBuffer self_t; - static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64; -private: - struct StaticAllocationMarker { }; - - AccumulatorBuffer(StaticAllocationMarker m) - : mStorageSize(0), - mStorage(NULL) - {} - -public: - - AccumulatorBuffer(const AccumulatorBuffer& other = *getDefaultBuffer()) - : mStorageSize(0), - mStorage(NULL) - { - resize(other.mStorageSize); - for (S32 i = 0; i < sNextStorageSlot; i++) - { - mStorage[i] = other.mStorage[i]; - } - } - - ~AccumulatorBuffer() - { - if (isPrimary()) - { - LLThreadLocalSingletonPointer::setInstance(NULL); - } - delete[] mStorage; - } - - LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index) - { - return mStorage[index]; - } - - LL_FORCE_INLINE const ACCUMULATOR& operator[](size_t index) const - { - return mStorage[index]; - } - - void addSamples(const AccumulatorBuffer& other, bool append = true) - { - llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize > sNextStorageSlot); - for (size_t i = 0; i < sNextStorageSlot; i++) - { - mStorage[i].addSamples(other.mStorage[i], append); - } - } - - void copyFrom(const AccumulatorBuffer& other) - { - llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize > sNextStorageSlot); - for (size_t i = 0; i < sNextStorageSlot; i++) - { - mStorage[i] = other.mStorage[i]; - } - } - - void reset(const AccumulatorBuffer* other = NULL) - { - llassert(mStorageSize >= sNextStorageSlot); - for (size_t i = 0; i < sNextStorageSlot; i++) - { - mStorage[i].reset(other ? &other->mStorage[i] : NULL); - } - } - - void flush(LLUnitImplicit time_stamp) - { - llassert(mStorageSize >= sNextStorageSlot); - for (size_t i = 0; i < sNextStorageSlot; i++) - { - mStorage[i].flush(time_stamp); - } - } - - void makePrimary() - { - LLThreadLocalSingletonPointer::setInstance(mStorage); - } - - bool isPrimary() const - { - return LLThreadLocalSingletonPointer::getInstance() == mStorage; - } - - LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage() - { - ACCUMULATOR* accumulator = LLThreadLocalSingletonPointer::getInstance(); - return accumulator ? accumulator : getDefaultBuffer()->mStorage; - } - - // NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned - size_t reserveSlot() - { -#ifndef LL_RELEASE_FOR_DOWNLOAD - if (LLTrace::isInitialized()) - { - llerrs << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << llendl; - } -#endif - size_t next_slot = sNextStorageSlot++; - if (next_slot >= mStorageSize) - { - resize(mStorageSize + (mStorageSize >> 2)); - } - llassert(mStorage && next_slot < mStorageSize); - return next_slot; - } - - void resize(size_t new_size) - { - if (new_size <= mStorageSize) return; - - ACCUMULATOR* old_storage = mStorage; - mStorage = new ACCUMULATOR[new_size]; - if (old_storage) - { - for (S32 i = 0; i < mStorageSize; i++) - { - mStorage[i] = old_storage[i]; - } - } - mStorageSize = new_size; - delete[] old_storage; - - self_t* default_buffer = getDefaultBuffer(); - if (this != default_buffer - && new_size > default_buffer->size()) - { - //NB: this is not thread safe, but we assume that all resizing occurs during static initialization - default_buffer->resize(new_size); - } - } - - size_t size() const - { - return getNumIndices(); - } - - static size_t getNumIndices() - { - return sNextStorageSlot; - } - - static self_t* getDefaultBuffer() - { - static bool sInitialized = false; - if (!sInitialized) - { - // this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data - // so as not to trigger an access violation - sDefaultBuffer = new AccumulatorBuffer(StaticAllocationMarker()); - sInitialized = true; - sDefaultBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE); - } - return sDefaultBuffer; - } - -private: - ACCUMULATOR* mStorage; - size_t mStorageSize; - static size_t sNextStorageSlot; - static self_t* sDefaultBuffer; -}; - -template size_t AccumulatorBuffer::sNextStorageSlot = 0; -template AccumulatorBuffer* AccumulatorBuffer::sDefaultBuffer = NULL; - template class TraceType : public LLInstanceTracker, std::string> @@ -290,344 +111,6 @@ protected: const size_t mAccumulatorIndex; }; -class EventAccumulator -{ -public: - typedef F64 value_t; - typedef F64 mean_t; - - EventAccumulator() - : mSum(0), - mMin((std::numeric_limits::max)()), - mMax((std::numeric_limits::min)()), - mMean(0), - mVarianceSum(0), - mNumSamples(0), - mLastValue(0) - {} - - void record(F64 value) - { - mNumSamples++; - mSum += value; - // NOTE: both conditions will hold on first pass through - if (value < mMin) - { - mMin = value; - } - if (value > mMax) - { - mMax = value; - } - F64 old_mean = mMean; - mMean += (value - old_mean) / (F64)mNumSamples; - mVarianceSum += (value - old_mean) * (value - mMean); - mLastValue = value; - } - - void addSamples(const EventAccumulator& other, bool append) - { - if (other.mNumSamples) - { - 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 = mVarianceSum / mNumSamples, - v_2 = other.mVarianceSum / other.mNumSamples; - if (n_1 == 0) - { - mVarianceSum = other.mVarianceSum; - } - else if (n_2 == 0) - { - // don't touch variance - // mVarianceSum = mVarianceSum; - } - else - { - mVarianceSum = (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) mLastValue = other.mLastValue; - } - } - - void reset(const EventAccumulator* other) - { - mNumSamples = 0; - mSum = 0; - mMin = std::numeric_limits::max(); - mMax = std::numeric_limits::min(); - mMean = 0; - mVarianceSum = 0; - mLastValue = other ? other->mLastValue : 0; - } - - void flush(LLUnitImplicit) {} - - F64 getSum() const { return mSum; } - F64 getMin() const { return mMin; } - F64 getMax() const { return mMax; } - F64 getLastValue() const { return mLastValue; } - F64 getMean() const { return mMean; } - F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mNumSamples); } - U32 getSampleCount() const { return mNumSamples; } - -private: - F64 mSum, - mMin, - mMax, - mLastValue; - - F64 mMean, - mVarianceSum; - - U32 mNumSamples; -}; - - -class SampleAccumulator -{ -public: - typedef F64 value_t; - typedef F64 mean_t; - - SampleAccumulator() - : mSum(0), - mMin((std::numeric_limits::max)()), - mMax((std::numeric_limits::min)()), - mMean(0), - mVarianceSum(0), - mLastSampleTimeStamp(LLTimer::getTotalSeconds()), - mTotalSamplingTime(0), - mNumSamples(0), - mLastValue(0), - mHasValue(false) - {} - - void sample(F64 value) - { - LLUnitImplicit time_stamp = LLTimer::getTotalSeconds(); - LLUnitImplicit delta_time = time_stamp - mLastSampleTimeStamp; - mLastSampleTimeStamp = time_stamp; - - if (mHasValue) - { - mTotalSamplingTime += delta_time; - mSum += mLastValue * delta_time; - - // NOTE: both conditions will hold first time through - if (value < mMin) { mMin = value; } - if (value > mMax) { mMax = value; } - - F64 old_mean = mMean; - mMean += (delta_time / mTotalSamplingTime) * (mLastValue - old_mean); - mVarianceSum += delta_time * (mLastValue - old_mean) * (mLastValue - mMean); - } - - mLastValue = value; - mNumSamples++; - mHasValue = true; - } - - void addSamples(const SampleAccumulator& other, bool append) - { - if (other.mTotalSamplingTime) - { - 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 = mTotalSamplingTime, - n_2 = other.mTotalSamplingTime; - F64 m_1 = mMean, - m_2 = other.mMean; - F64 v_1 = mVarianceSum / mTotalSamplingTime, - v_2 = other.mVarianceSum / other.mTotalSamplingTime; - if (n_1 == 0) - { - mVarianceSum = other.mVarianceSum; - } - else if (n_2 == 0) - { - // variance is unchanged - // mVarianceSum = mVarianceSum; - } - else - { - mVarianceSum = mTotalSamplingTime - * ((((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)); - } - - 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) - { - mLastValue = other.mLastValue; - mLastSampleTimeStamp = other.mLastSampleTimeStamp; - mHasValue |= other.mHasValue; - } - } - } - - void reset(const SampleAccumulator* other) - { - mNumSamples = 0; - mSum = 0; - mMin = std::numeric_limits::max(); - mMax = std::numeric_limits::min(); - mMean = other ? other->mLastValue : 0; - mVarianceSum = 0; - mLastSampleTimeStamp = LLTimer::getTotalSeconds(); - mTotalSamplingTime = 0; - mLastValue = other ? other->mLastValue : 0; - mHasValue = other ? other->mHasValue : false; - } - - void flush(LLUnitImplicit time_stamp) - { - LLUnitImplicit delta_time = time_stamp - mLastSampleTimeStamp; - - if (mHasValue) - { - mSum += mLastValue * delta_time; - mTotalSamplingTime += delta_time; - } - mLastSampleTimeStamp = time_stamp; - } - - F64 getSum() const { return mSum; } - F64 getMin() const { return mMin; } - F64 getMax() const { return mMax; } - F64 getLastValue() const { return mLastValue; } - F64 getMean() const { return mMean; } - F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mTotalSamplingTime); } - U32 getSampleCount() const { return mNumSamples; } - -private: - F64 mSum, - mMin, - mMax, - mLastValue; - - bool mHasValue; - - F64 mMean, - mVarianceSum; - - LLUnitImplicit mLastSampleTimeStamp, - mTotalSamplingTime; - - U32 mNumSamples; -}; - -class CountAccumulator -{ -public: - typedef F64 value_t; - typedef F64 mean_t; - - CountAccumulator() - : mSum(0), - mNumSamples(0) - {} - - void add(F64 value) - { - mNumSamples++; - mSum += value; - } - - void addSamples(const CountAccumulator& other, bool /*append*/) - { - mSum += other.mSum; - mNumSamples += other.mNumSamples; - } - - void reset(const CountAccumulator* other) - { - mNumSamples = 0; - mSum = 0; - } - - void flush(LLUnitImplicit) {} - - F64 getSum() const { return mSum; } - - U32 getSampleCount() const { return mNumSamples; } - -private: - F64 mSum; - - U32 mNumSamples; -}; - -class TimeBlockAccumulator -{ -public: - typedef LLUnit value_t; - typedef LLUnit mean_t; - typedef TimeBlockAccumulator self_t; - - // fake classes that allows us to view different facets of underlying statistic - struct CallCountFacet - { - typedef U32 value_t; - typedef F32 mean_t; - }; - - struct SelfTimeFacet - { - typedef LLUnit value_t; - typedef LLUnit mean_t; - }; - - TimeBlockAccumulator(); - void addSamples(const self_t& other, bool /*append*/); - void reset(const self_t* other); - void flush(LLUnitImplicit) {} - - // - // members - // - U64 mStartTotalTimeCounter, - mTotalTimeCounter, - mSelfTimeCounter; - U32 mCalls; - class TimeBlock* mParent; // last acknowledged parent of this time block - class TimeBlock* mLastCaller; // used to bootstrap tree construction - 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 - -}; template<> class TraceType @@ -651,23 +134,6 @@ public: {} }; -class TimeBlock; -class TimeBlockTreeNode -{ -public: - TimeBlockTreeNode(); - - void setParent(TimeBlock* parent); - TimeBlock* getParent() { return mParent; } - - TimeBlock* mBlock; - TimeBlock* mParent; - std::vector mChildren; - bool mCollapsed; - bool mNeedsSorting; -}; - - template class EventStatHandle : public TraceType @@ -735,64 +201,6 @@ void add(CountStatHandle& count, VALUE_T value) count.getPrimaryAccumulator()->add(storage_value(converted_value)); } - -struct MemStatAccumulator -{ - typedef MemStatAccumulator self_t; - - // fake classes that allows us to view different facets of underlying statistic - struct AllocationCountFacet - { - typedef U32 value_t; - typedef F32 mean_t; - }; - - struct DeallocationCountFacet - { - typedef U32 value_t; - typedef F32 mean_t; - }; - - struct ChildMemFacet - { - typedef LLUnit value_t; - typedef LLUnit mean_t; - }; - - MemStatAccumulator() - : mAllocatedCount(0), - mDeallocatedCount(0) - {} - - void addSamples(const MemStatAccumulator& other, bool append) - { - mSize.addSamples(other.mSize, append); - mChildSize.addSamples(other.mChildSize, append); - mAllocatedCount += other.mAllocatedCount; - mDeallocatedCount += other.mDeallocatedCount; - } - - void reset(const MemStatAccumulator* other) - { - mSize.reset(other ? &other->mSize : NULL); - mChildSize.reset(other ? &other->mChildSize : NULL); - mAllocatedCount = 0; - mDeallocatedCount = 0; - } - - void flush(LLUnitImplicit time_stamp) - { - mSize.flush(time_stamp); - mChildSize.flush(time_stamp); - } - - SampleAccumulator mSize, - mChildSize; - int mAllocatedCount, - mDeallocatedCount; -}; - - template<> class TraceType : public TraceType -- cgit v1.2.3 From 04bdc8ba83c297945dd60489c241b88adf892ff4 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 1 Jul 2013 17:04:01 -0700 Subject: SH-4294 FIX Interesting: Statistics Texture cache hit rate is always 0% also, removed LLTrace::init and cleanup removed derived class implementation of memory stat for LLMemTrackable is automatic now --- indra/llcommon/lltrace.h | 68 +++++++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 27 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 72ef51c232..1cde450dc2 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -53,19 +53,29 @@ STORAGE_TYPE storage_value(LLUnit val) { return val.val template STORAGE_TYPE storage_value(LLUnitImplicit val) { return val.value(); } -void init(); -void cleanup(); -bool isInitialized(); +class TraceBase +{ +public: + TraceBase(const char* name, const char* description); + virtual ~TraceBase() {}; + virtual const char* getUnitLabel(); + + const std::string& getName() const { return mName; } + +protected: + const std::string mName; + const std::string mDescription; +}; template class TraceType -: public LLInstanceTracker, std::string> +: public TraceBase, + public LLInstanceTracker, std::string> { public: TraceType(const char* name, const char* description = NULL) : LLInstanceTracker, std::string>(name), - mName(name), - mDescription(description ? description : ""), + TraceBase(name, description), mAccumulatorIndex(AccumulatorBuffer::getDefaultBuffer()->reserveSlot()) {} @@ -78,13 +88,7 @@ public: size_t getIndex() const { return mAccumulatorIndex; } static size_t getNumIndices() { return AccumulatorBuffer::getNumIndices(); } - virtual const char* getUnitLabel() { return ""; } - - const std::string& getName() const { return mName; } - -protected: - const std::string mName; - const std::string mDescription; +private: const size_t mAccumulatorIndex; }; @@ -320,7 +324,7 @@ class MemTrackable template struct TrackMemImpl; - typedef MemTrackable mem_trackable_t; + typedef MemTrackable mem_trackable_t; public: typedef void mem_trackable_tag_t; @@ -332,7 +336,7 @@ public: void* operator new(size_t size) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = mem_trackable_t::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size); @@ -344,7 +348,7 @@ public: void operator delete(void* ptr, size_t size) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = mem_trackable_t::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size); @@ -356,7 +360,7 @@ public: void *operator new [](size_t size) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = mem_trackable_t::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size); @@ -368,7 +372,7 @@ public: void operator delete[](void* ptr, size_t size) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = mem_trackable_t::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size); @@ -394,14 +398,16 @@ public: } - void memClaimAmount(size_t size) + template + AMOUNT_T& memClaimAmount(AMOUNT_T& size) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); - mMemFootprint += size; + MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator(); + mMemFootprint += (size_t)size; if (accumulator) { accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size); } + return size; } // remove memory we had claimed from our calculated footprint @@ -419,24 +425,28 @@ public: return value; } - void memDisclaimAmount(size_t size) + template + AMOUNT_T& memDisclaimAmount(AMOUNT_T& size) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size); } + return size; } private: size_t mMemFootprint; + static MemStatHandle sMemStat; + template struct TrackMemImpl { static void claim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator(); if (accumulator) { size_t footprint = MemFootprint::measure(tracked); @@ -447,7 +457,7 @@ private: static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator(); if (accumulator) { size_t footprint = MemFootprint::measure(tracked); @@ -462,7 +472,7 @@ private: { static void claim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mChildSize.sample(accumulator->mChildSize.getLastValue() + (F64)MemFootprint::measure(tracked)); @@ -471,7 +481,7 @@ private: static void disclaim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mChildSize.sample(accumulator->mChildSize.getLastValue() - (F64)MemFootprint::measure(tracked)); @@ -480,5 +490,9 @@ private: }; }; +template +MemStatHandle MemTrackable::sMemStat(typeid(DERIVED).name()); + + } #endif // LL_LLTRACE_H -- cgit v1.2.3 From 8208a40412fac35593d4b8b13f43c6be5e4d6990 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 1 Jul 2013 18:50:51 -0700 Subject: BUILDFIX: reverted changes that attempted to automate mem track stat definition as they don't work on gcc/clang --- indra/llcommon/lltrace.h | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 1cde450dc2..e2c4b63276 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -336,7 +336,7 @@ public: void* operator new(size_t size) { - MemStatAccumulator* accumulator = mem_trackable_t::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size); @@ -348,7 +348,7 @@ public: void operator delete(void* ptr, size_t size) { - MemStatAccumulator* accumulator = mem_trackable_t::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size); @@ -360,7 +360,7 @@ public: void *operator new [](size_t size) { - MemStatAccumulator* accumulator = mem_trackable_t::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size); @@ -372,7 +372,7 @@ public: void operator delete[](void* ptr, size_t size) { - MemStatAccumulator* accumulator = mem_trackable_t::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size); @@ -438,15 +438,13 @@ public: private: size_t mMemFootprint; - static MemStatHandle sMemStat; - template struct TrackMemImpl { static void claim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { size_t footprint = MemFootprint::measure(tracked); @@ -457,7 +455,7 @@ private: static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { size_t footprint = MemFootprint::measure(tracked); @@ -472,7 +470,7 @@ private: { static void claim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mChildSize.sample(accumulator->mChildSize.getLastValue() + (F64)MemFootprint::measure(tracked)); @@ -481,7 +479,7 @@ private: static void disclaim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mChildSize.sample(accumulator->mChildSize.getLastValue() - (F64)MemFootprint::measure(tracked)); @@ -490,9 +488,5 @@ private: }; }; -template -MemStatHandle MemTrackable::sMemStat(typeid(DERIVED).name()); - - } #endif // LL_LLTRACE_H -- cgit v1.2.3 From 048638e5ffec0cc08d79484412790b51558942fe Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 1 Jul 2013 19:26:56 -0700 Subject: BUILDFIX: missed a couple of scope qualifiers --- indra/llcommon/lltrace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index e2c4b63276..2c45923aac 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -401,7 +401,7 @@ public: template AMOUNT_T& memClaimAmount(AMOUNT_T& size) { - MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); mMemFootprint += (size_t)size; if (accumulator) { @@ -428,7 +428,7 @@ public: template AMOUNT_T& memDisclaimAmount(AMOUNT_T& size) { - MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator(); + MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size); -- cgit v1.2.3 From d122318bef2ff0eced7641dc24f411f792bd2935 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 8 Jul 2013 00:55:17 -0700 Subject: SH-4299 WIP: Interesting: High fps shown temporarily off scale in statistics console added percentage/ratio units added auto-range and auto tick calculation to stat bar to automate display stats --- indra/llcommon/lltrace.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 2c45923aac..2c84b1596a 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -61,6 +61,7 @@ public: virtual const char* getUnitLabel(); const std::string& getName() const { return mName; } + const std::string& getDescription() const { return mDescription; } protected: const std::string mName; @@ -169,7 +170,7 @@ public: typedef TraceType trace_t; CountStatHandle(const char* name, const char* description = NULL) - : trace_t(name) + : trace_t(name, description) {} /*virtual*/ const char* getUnitLabel() { return LLGetUnitLabel::getUnitLabel(); } -- cgit v1.2.3 From 075a7bcc980b0ca0d2888d344b6afa8ab5b52d85 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 18 Jul 2013 15:09:45 -0700 Subject: SH-4297 WIP interesting: viewer-interesting starts loading cached scene late dependency cleanup - removed a lot of unecessary includes --- indra/llcommon/lltrace.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 2c84b1596a..75e913a348 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -123,6 +123,7 @@ class EventStatHandle public: typedef F64 storage_t; typedef TraceType trace_t; + typedef EventStatHandle self_t; EventStatHandle(const char* name, const char* description = NULL) : trace_t(name, description) @@ -146,6 +147,7 @@ class SampleStatHandle public: typedef F64 storage_t; typedef TraceType trace_t; + typedef SampleStatHandle self_t; SampleStatHandle(const char* name, const char* description = NULL) : trace_t(name, description) @@ -168,6 +170,7 @@ class CountStatHandle public: typedef F64 storage_t; typedef TraceType trace_t; + typedef CountStatHandle self_t; CountStatHandle(const char* name, const char* description = NULL) : trace_t(name, description) -- cgit v1.2.3 From cc31b4ae7934010762b8aaaa7e190c74a1cd7820 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 12 Aug 2013 20:05:16 -0700 Subject: SH-4399 FIX: Interesting: Texture console MB Bound 0/384 and texture queue bounces once per second SH-4346 FIX: Interesting: some integer Statistics are displayed as floating point after crossing region boundary made llerrs/infos/etc properly variadic wrt tags LL_INFOS("A", "B", "C") works, for example fixed unit tests remove llsimplestat --- indra/llcommon/lltrace.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 75e913a348..1f86aadaba 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -58,7 +58,7 @@ class TraceBase public: TraceBase(const char* name, const char* description); virtual ~TraceBase() {}; - virtual const char* getUnitLabel(); + virtual const char* getUnitLabel() const; const std::string& getName() const { return mName; } const std::string& getDescription() const { return mDescription; } @@ -129,7 +129,7 @@ public: : trace_t(name, description) {} - /*virtual*/ const char* getUnitLabel() { return LLGetUnitLabel::getUnitLabel(); } + /*virtual*/ const char* getUnitLabel() const { return LLGetUnitLabel::getUnitLabel(); } }; @@ -153,7 +153,7 @@ public: : trace_t(name, description) {} - /*virtual*/ const char* getUnitLabel() { return LLGetUnitLabel::getUnitLabel(); } + /*virtual*/ const char* getUnitLabel() const { return LLGetUnitLabel::getUnitLabel(); } }; template @@ -176,7 +176,7 @@ public: : trace_t(name, description) {} - /*virtual*/ const char* getUnitLabel() { return LLGetUnitLabel::getUnitLabel(); } + /*virtual*/ const char* getUnitLabel() const { return LLGetUnitLabel::getUnitLabel(); } }; template @@ -227,7 +227,7 @@ public: : trace_t(name) {} - /*virtual*/ const char* getUnitLabel() { return "B"; } + /*virtual*/ const char* getUnitLabel() const { return "B"; } TraceType& allocationCount() { -- cgit v1.2.3 From 2c6bc5afa59a88136fd6de4ebf0cb99ea7cdef3f Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 21 Aug 2013 14:06:57 -0700 Subject: SH-4433 WIP Interesting: Statistics > Ping Sim is always 0 ms made getPrimaryAccumulator return a reference since it was an always non-null pointer changed unit conversion to perform lazy division in order to avoid truncation of timer values --- indra/llcommon/lltrace.h | 100 +++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 65 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 1f86aadaba..bf8e950a8c 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -80,10 +80,10 @@ public: mAccumulatorIndex(AccumulatorBuffer::getDefaultBuffer()->reserveSlot()) {} - LL_FORCE_INLINE ACCUMULATOR* getPrimaryAccumulator() const + LL_FORCE_INLINE ACCUMULATOR& getPrimaryAccumulator() const { ACCUMULATOR* accumulator_storage = AccumulatorBuffer::getPrimaryStorage(); - return &accumulator_storage[mAccumulatorIndex]; + return accumulator_storage[mAccumulatorIndex]; } size_t getIndex() const { return mAccumulatorIndex; } @@ -137,7 +137,7 @@ template void record(EventStatHandle& measurement, VALUE_T value) { T converted_value(value); - measurement.getPrimaryAccumulator()->record(storage_value(converted_value)); + measurement.getPrimaryAccumulator().record(storage_value(converted_value)); } template @@ -160,7 +160,7 @@ template void sample(SampleStatHandle& measurement, VALUE_T value) { T converted_value(value); - measurement.getPrimaryAccumulator()->sample(storage_value(converted_value)); + measurement.getPrimaryAccumulator().sample(storage_value(converted_value)); } template @@ -183,7 +183,7 @@ template void add(CountStatHandle& count, VALUE_T value) { T converted_value(value); - count.getPrimaryAccumulator()->add(storage_value(converted_value)); + count.getPrimaryAccumulator().add(storage_value(converted_value)); } template<> @@ -340,49 +340,37 @@ public: void* operator new(size_t size) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); - if (accumulator) - { - accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size); - accumulator->mAllocatedCount++; - } + MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); + accumulator.mAllocatedCount++; return ::operator new(size); } void operator delete(void* ptr, size_t size) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); - if (accumulator) - { - accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size); - accumulator->mAllocatedCount--; - accumulator->mDeallocatedCount++; - } + MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); + accumulator.mAllocatedCount--; + accumulator.mDeallocatedCount++; ::operator delete(ptr); } void *operator new [](size_t size) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); - if (accumulator) - { - accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size); - accumulator->mAllocatedCount++; - } + MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); + accumulator.mAllocatedCount++; return ::operator new[](size); } void operator delete[](void* ptr, size_t size) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); - if (accumulator) - { - accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size); - accumulator->mAllocatedCount--; - accumulator->mDeallocatedCount++; - } + MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); + accumulator.mAllocatedCount--; + accumulator.mDeallocatedCount++; ::operator delete[](ptr); } @@ -405,12 +393,9 @@ public: template AMOUNT_T& memClaimAmount(AMOUNT_T& size) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); mMemFootprint += (size_t)size; - if (accumulator) - { - accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size); - } + accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); return size; } @@ -432,11 +417,8 @@ public: template AMOUNT_T& memDisclaimAmount(AMOUNT_T& size) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); - if (accumulator) - { - accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size); - } + MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); return size; } @@ -448,24 +430,18 @@ private: { static void claim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); - if (accumulator) - { - size_t footprint = MemFootprint::measure(tracked); - accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)footprint); - tracker.mMemFootprint += footprint; - } + MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + size_t footprint = MemFootprint::measure(tracked); + accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)footprint : (F64)footprint); + tracker.mMemFootprint += footprint; } static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); - if (accumulator) - { - size_t footprint = MemFootprint::measure(tracked); - accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)footprint); - tracker.mMemFootprint -= footprint; - } + MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + size_t footprint = MemFootprint::measure(tracked); + accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)footprint : -(F64)footprint); + tracker.mMemFootprint -= footprint; } }; @@ -474,20 +450,14 @@ private: { static void claim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); - if (accumulator) - { - accumulator->mChildSize.sample(accumulator->mChildSize.getLastValue() + (F64)MemFootprint::measure(tracked)); - } + MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + accumulator.mChildSize.sample(accumulator.mChildSize.hasValue() ? accumulator.mChildSize.getLastValue() + (F64)MemFootprint::measure(tracked) : (F64)MemFootprint::measure(tracked)); } static void disclaim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); - if (accumulator) - { - accumulator->mChildSize.sample(accumulator->mChildSize.getLastValue() - (F64)MemFootprint::measure(tracked)); - } + MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + accumulator.mChildSize.sample(accumulator.mChildSize.hasValue() ? accumulator.mChildSize.getLastValue() - (F64)MemFootprint::measure(tracked) : -(F64)MemFootprint::measure(tracked)); } }; }; -- cgit v1.2.3 From cbe397ad13665c7bc993e10d8fe1e4a876253378 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 5 Sep 2013 14:04:13 -0700 Subject: changed fast timer over to using macro another attempt to move mem stat into base class --- indra/llcommon/lltrace.h | 100 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 82 insertions(+), 18 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index bf8e950a8c..a465a7f426 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -38,8 +38,6 @@ #include -#define LL_RECORD_BLOCK_TIME(block_timer) LLTrace::TimeBlock::Recorder LL_GLUE_TOKENS(block_time_recorder, __COUNTER__)(block_timer); - namespace LLTrace { class Recording; @@ -89,7 +87,7 @@ public: size_t getIndex() const { return mAccumulatorIndex; } static size_t getNumIndices() { return AccumulatorBuffer::getNumIndices(); } -private: +protected: const size_t mAccumulatorIndex; }; @@ -329,7 +327,7 @@ class MemTrackable struct TrackMemImpl; typedef MemTrackable mem_trackable_t; - + static MemStatHandle sMemStat; public: typedef void mem_trackable_tag_t; @@ -340,38 +338,100 @@ public: void* operator new(size_t size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); accumulator.mAllocatedCount++; - return ::operator new(size); + if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) + { + return ::operator new(size); + } + else if (ALIGNMENT == 16) + { + return ll_aligned_malloc_16(size); + } + else if (ALIGNMENT == 32) + { + return ll_aligned_malloc_32(size); + } + else + { + return ll_aligned_malloc(size, ALIGNMENT); + } } void operator delete(void* ptr, size_t size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); accumulator.mAllocatedCount--; accumulator.mDeallocatedCount++; - ::operator delete(ptr); + + if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) + { + ::operator delete(ptr); + } + else if (ALIGNMENT == 16) + { + ll_aligned_free_16(ptr); + } + else if (ALIGNMENT == 32) + { + return ll_aligned_free_32(ptr); + } + else + { + return ll_aligned_free(ptr); + } } void *operator new [](size_t size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); accumulator.mAllocatedCount++; - return ::operator new[](size); + if (alignment == LL_DEFAULT_HEAP_ALIGN) + { + return ::operator new[](size); + } + else if (ALIGNMENT == 16) + { + return ll_aligned_malloc_16(size); + } + else if (ALIGNMENT == 32) + { + return ll_aligned_malloc_32(size); + } + else + { + return ll_aligned_malloc(size, ALIGNMENT); + } } void operator delete[](void* ptr, size_t size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); accumulator.mAllocatedCount--; accumulator.mDeallocatedCount++; - ::operator delete[](ptr); + + if (alignment == LL_DEFAULT_HEAP_ALIGN) + { + ::operator delete[](ptr); + } + else if (ALIGNMENT == 16) + { + ll_aligned_free_16(ptr); + } + else if (ALIGNMENT == 32) + { + return ll_aligned_free_32(ptr); + } + else + { + return ll_aligned_free(ptr); + } } // claim memory associated with other objects/data as our own, adding to our calculated footprint @@ -393,7 +453,7 @@ public: template AMOUNT_T& memClaimAmount(AMOUNT_T& size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); mMemFootprint += (size_t)size; accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); return size; @@ -417,7 +477,7 @@ public: template AMOUNT_T& memDisclaimAmount(AMOUNT_T& size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); return size; } @@ -430,7 +490,7 @@ private: { static void claim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); size_t footprint = MemFootprint::measure(tracked); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)footprint : (F64)footprint); tracker.mMemFootprint += footprint; @@ -438,7 +498,7 @@ private: static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); size_t footprint = MemFootprint::measure(tracked); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)footprint : -(F64)footprint); tracker.mMemFootprint -= footprint; @@ -450,17 +510,21 @@ private: { static void claim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); accumulator.mChildSize.sample(accumulator.mChildSize.hasValue() ? accumulator.mChildSize.getLastValue() + (F64)MemFootprint::measure(tracked) : (F64)MemFootprint::measure(tracked)); } static void disclaim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); accumulator.mChildSize.sample(accumulator.mChildSize.hasValue() ? accumulator.mChildSize.getLastValue() - (F64)MemFootprint::measure(tracked) : -(F64)MemFootprint::measure(tracked)); } }; }; +// pretty sure typeid of containing class in static object constructor doesn't work in gcc +template +MemStatHandle MemTrackable::sMemStat(typeid(DERIVED).name()); + } #endif // LL_LLTRACE_H -- cgit v1.2.3 From 4032c518e49348ad0180b47d73bb73036bab5f73 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 5 Sep 2013 15:33:04 -0700 Subject: BUILDFIX: type typo --- indra/llcommon/lltrace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index a465a7f426..d42c8e26fb 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -391,7 +391,7 @@ public: accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); accumulator.mAllocatedCount++; - if (alignment == LL_DEFAULT_HEAP_ALIGN) + if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) { return ::operator new[](size); } @@ -416,7 +416,7 @@ public: accumulator.mAllocatedCount--; accumulator.mDeallocatedCount++; - if (alignment == LL_DEFAULT_HEAP_ALIGN) + if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) { ::operator delete[](ptr); } -- cgit v1.2.3 From 3fd68662f267a3fd96d101834b3a9563bde3f61e Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sat, 7 Sep 2013 21:16:39 -0700 Subject: added memory usage and occlusion events to traces renamed "current" to "primary" when referring to accumulators --- indra/llcommon/lltrace.h | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index bf8e950a8c..cda15c0de5 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -80,9 +80,9 @@ public: mAccumulatorIndex(AccumulatorBuffer::getDefaultBuffer()->reserveSlot()) {} - LL_FORCE_INLINE ACCUMULATOR& getPrimaryAccumulator() const + LL_FORCE_INLINE ACCUMULATOR& getCurrentAccumulator() const { - ACCUMULATOR* accumulator_storage = AccumulatorBuffer::getPrimaryStorage(); + ACCUMULATOR* accumulator_storage = AccumulatorBuffer::getCurrentStorage(); return accumulator_storage[mAccumulatorIndex]; } @@ -137,7 +137,7 @@ template void record(EventStatHandle& measurement, VALUE_T value) { T converted_value(value); - measurement.getPrimaryAccumulator().record(storage_value(converted_value)); + measurement.getCurrentAccumulator().record(storage_value(converted_value)); } template @@ -160,7 +160,22 @@ template void sample(SampleStatHandle& measurement, VALUE_T value) { T converted_value(value); - measurement.getPrimaryAccumulator().sample(storage_value(converted_value)); + measurement.getCurrentAccumulator().sample(storage_value(converted_value)); +} + +template +void add(SampleStatHandle& measurement, VALUE_T value) +{ + T converted_value(value); + SampleAccumulator& acc = measurement.getCurrentAccumulator(); + if (acc.hasValue()) + { + acc.sample(acc.getLastValue() + converted_value); + } + else + { + acc.sample(converted_value); + } } template @@ -183,7 +198,7 @@ template void add(CountStatHandle& count, VALUE_T value) { T converted_value(value); - count.getPrimaryAccumulator().add(storage_value(converted_value)); + count.getCurrentAccumulator().add(storage_value(converted_value)); } template<> @@ -340,7 +355,7 @@ public: void* operator new(size_t size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); accumulator.mAllocatedCount++; @@ -349,7 +364,7 @@ public: void operator delete(void* ptr, size_t size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); accumulator.mAllocatedCount--; accumulator.mDeallocatedCount++; @@ -358,7 +373,7 @@ public: void *operator new [](size_t size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); accumulator.mAllocatedCount++; @@ -367,7 +382,7 @@ public: void operator delete[](void* ptr, size_t size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); accumulator.mAllocatedCount--; accumulator.mDeallocatedCount++; @@ -393,7 +408,7 @@ public: template AMOUNT_T& memClaimAmount(AMOUNT_T& size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); mMemFootprint += (size_t)size; accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); return size; @@ -417,7 +432,7 @@ public: template AMOUNT_T& memDisclaimAmount(AMOUNT_T& size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); return size; } @@ -430,7 +445,7 @@ private: { static void claim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); size_t footprint = MemFootprint::measure(tracked); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)footprint : (F64)footprint); tracker.mMemFootprint += footprint; @@ -438,7 +453,7 @@ private: static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); size_t footprint = MemFootprint::measure(tracked); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)footprint : -(F64)footprint); tracker.mMemFootprint -= footprint; @@ -450,13 +465,13 @@ private: { static void claim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); accumulator.mChildSize.sample(accumulator.mChildSize.hasValue() ? accumulator.mChildSize.getLastValue() + (F64)MemFootprint::measure(tracked) : (F64)MemFootprint::measure(tracked)); } static void disclaim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); accumulator.mChildSize.sample(accumulator.mChildSize.hasValue() ? accumulator.mChildSize.getLastValue() - (F64)MemFootprint::measure(tracked) : -(F64)MemFootprint::measure(tracked)); } }; -- cgit v1.2.3 From ebd62051a5b2cb1ffcfa2fccc6e6d4292039fdda Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sat, 7 Sep 2013 22:15:41 -0700 Subject: memory stat for MemTrackable has name lazily initialized in an attempt to get around link time error for unit tests on gcc --- indra/llcommon/lltrace.h | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 6436570492..9713bd6c04 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -62,8 +62,8 @@ public: const std::string& getDescription() const { return mDescription; } protected: - const std::string mName; - const std::string mDescription; + std::string mName; + std::string mDescription; }; template @@ -240,6 +240,11 @@ public: : trace_t(name) {} + void setName(const char* name) + { + mName = name; + } + /*virtual*/ const char* getUnitLabel() const { return "B"; } TraceType& allocationCount() @@ -346,6 +351,16 @@ class MemTrackable public: typedef void mem_trackable_tag_t; + MemTrackable() + { + static bool name_initialized = false; + if (!name_initialized) + { + name_initialized = true; + sMemStat.setName(typeid(DERIVED).name()); + } + } + virtual ~MemTrackable() { memDisclaim(mMemFootprint); @@ -353,7 +368,7 @@ public: void* operator new(size_t size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); accumulator.mAllocatedCount++; @@ -377,7 +392,7 @@ public: void operator delete(void* ptr, size_t size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); accumulator.mAllocatedCount--; accumulator.mDeallocatedCount++; @@ -402,7 +417,7 @@ public: void *operator new [](size_t size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); accumulator.mAllocatedCount++; @@ -426,7 +441,7 @@ public: void operator delete[](void* ptr, size_t size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); accumulator.mAllocatedCount--; accumulator.mDeallocatedCount++; @@ -468,7 +483,7 @@ public: template AMOUNT_T& memClaimAmount(AMOUNT_T& size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); mMemFootprint += (size_t)size; accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); return size; @@ -492,7 +507,7 @@ public: template AMOUNT_T& memDisclaimAmount(AMOUNT_T& size) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); return size; } @@ -505,7 +520,7 @@ private: { static void claim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); size_t footprint = MemFootprint::measure(tracked); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)footprint : (F64)footprint); tracker.mMemFootprint += footprint; @@ -513,7 +528,7 @@ private: static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); size_t footprint = MemFootprint::measure(tracked); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)footprint : -(F64)footprint); tracker.mMemFootprint -= footprint; @@ -525,21 +540,20 @@ private: { static void claim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); accumulator.mChildSize.sample(accumulator.mChildSize.hasValue() ? accumulator.mChildSize.getLastValue() + (F64)MemFootprint::measure(tracked) : (F64)MemFootprint::measure(tracked)); } static void disclaim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); accumulator.mChildSize.sample(accumulator.mChildSize.hasValue() ? accumulator.mChildSize.getLastValue() - (F64)MemFootprint::measure(tracked) : -(F64)MemFootprint::measure(tracked)); } }; }; -// pretty sure typeid of containing class in static object constructor doesn't work in gcc template -MemStatHandle MemTrackable::sMemStat(typeid(DERIVED).name()); +MemStatHandle MemTrackable::sMemStat(""); } #endif // LL_LLTRACE_H -- cgit v1.2.3 From 5f7f84c7acb686659b2bdc9a018b18c2b23db3d0 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sun, 8 Sep 2013 11:35:53 -0700 Subject: forgot to update instancetracker key when lazily generating name for memstat trace --- indra/llcommon/lltrace.h | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 9713bd6c04..f7ceaf585d 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -243,6 +243,7 @@ public: void setName(const char* name) { mName = name; + setKey(name); } /*virtual*/ const char* getUnitLabel() const { return "B"; } -- cgit v1.2.3 From 72f979135b3497d16c2635babf057900ddbc42fe Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 18 Sep 2013 14:20:30 -0700 Subject: merge --- indra/llcommon/lltrace.h | 81 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 25 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index f7ceaf585d..472f0b0cf0 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -80,8 +80,8 @@ public: LL_FORCE_INLINE ACCUMULATOR& getCurrentAccumulator() const { - ACCUMULATOR* accumulator_storage = AccumulatorBuffer::getCurrentStorage(); - return accumulator_storage[mAccumulatorIndex]; + ACCUMULATOR* accumulator_storage = LLThreadLocalSingletonPointer::getInstance(); + return accumulator_storage ? accumulator_storage[mAccumulatorIndex] : (*AccumulatorBuffer::getDefaultBuffer())[mAccumulatorIndex]; } size_t getIndex() const { return mAccumulatorIndex; } @@ -222,7 +222,7 @@ public: }; template<> -class TraceType +class TraceType : public TraceType { public: @@ -258,12 +258,51 @@ public: return static_cast&>(*(TraceType*)this); } - TraceType& childMem() + TraceType& childMem() { - return static_cast&>(*(TraceType*)this); + return static_cast&>(*(TraceType*)this); } }; +inline void track_alloc(MemStatHandle& measurement, size_t size) +{ + MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); + accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); + accumulator.mAllocatedCount++; +} + +inline void track_dealloc(MemStatHandle& measurement, size_t size) +{ + MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); + accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); + accumulator.mAllocatedCount--; + accumulator.mDeallocatedCount++; +} + +inline void claim_mem(MemStatHandle& measurement, size_t size) +{ + MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); + accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); +} + +inline void disclaim_mem(MemStatHandle& measurement, size_t size) +{ + MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); + accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); +} + +inline void claim_shadow_mem(MemStatHandle& measurement, size_t size) +{ + MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); + accumulator.mShadowSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); +} + +inline void disclaim_shadow_mem(MemStatHandle& measurement, size_t size) +{ + MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); + accumulator.mShadowSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); +} + // measures effective memory footprint of specified type // specialize to cover different types @@ -369,9 +408,7 @@ public: void* operator new(size_t size) { - MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); - accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); - accumulator.mAllocatedCount++; + track_alloc(sMemStat, size); if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) { @@ -393,10 +430,7 @@ public: void operator delete(void* ptr, size_t size) { - MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); - accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); - accumulator.mAllocatedCount--; - accumulator.mDeallocatedCount++; + track_dealloc(sMemStat, size); if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) { @@ -418,9 +452,7 @@ public: void *operator new [](size_t size) { - MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); - accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); - accumulator.mAllocatedCount++; + track_alloc(sMemStat, size); if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) { @@ -442,7 +474,7 @@ public: void operator delete[](void* ptr, size_t size) { - MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); accumulator.mAllocatedCount--; accumulator.mDeallocatedCount++; @@ -484,9 +516,8 @@ public: template AMOUNT_T& memClaimAmount(AMOUNT_T& size) { - MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); mMemFootprint += (size_t)size; - accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); return size; } @@ -508,7 +539,7 @@ public: template AMOUNT_T& memDisclaimAmount(AMOUNT_T& size) { - MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); return size; } @@ -521,17 +552,17 @@ private: { static void claim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); size_t footprint = MemFootprint::measure(tracked); - accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)footprint : (F64)footprint); + claim_mem(sMemStat, footprint); tracker.mMemFootprint += footprint; } static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); size_t footprint = MemFootprint::measure(tracked); - accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)footprint : -(F64)footprint); + disclaim_mem(sMemStat, footprint); tracker.mMemFootprint -= footprint; } }; @@ -541,13 +572,13 @@ private: { static void claim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); accumulator.mChildSize.sample(accumulator.mChildSize.hasValue() ? accumulator.mChildSize.getLastValue() + (F64)MemFootprint::measure(tracked) : (F64)MemFootprint::measure(tracked)); } static void disclaim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); accumulator.mChildSize.sample(accumulator.mChildSize.hasValue() ? accumulator.mChildSize.getLastValue() - (F64)MemFootprint::measure(tracked) : -(F64)MemFootprint::measure(tracked)); } }; -- cgit v1.2.3 From f5ca3695f22fa52b4d6b2db9c8a9e10a78869518 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 18 Sep 2013 14:45:15 -0700 Subject: BUILDFIX: bad merge --- indra/llcommon/lltrace.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 472f0b0cf0..3cc0d16b93 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -539,8 +539,7 @@ public: template AMOUNT_T& memDisclaimAmount(AMOUNT_T& size) { - MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); - accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); + disclaim_mem(size); return size; } @@ -552,7 +551,6 @@ private: { static void claim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); size_t footprint = MemFootprint::measure(tracked); claim_mem(sMemStat, footprint); tracker.mMemFootprint += footprint; @@ -560,7 +558,6 @@ private: static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked) { - MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); size_t footprint = MemFootprint::measure(tracked); disclaim_mem(sMemStat, footprint); tracker.mMemFootprint -= footprint; @@ -572,13 +569,11 @@ private: { static void claim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); accumulator.mChildSize.sample(accumulator.mChildSize.hasValue() ? accumulator.mChildSize.getLastValue() + (F64)MemFootprint::measure(tracked) : (F64)MemFootprint::measure(tracked)); } static void disclaim(mem_trackable_t& tracker, TRACKED& tracked) { - MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); accumulator.mChildSize.sample(accumulator.mChildSize.hasValue() ? accumulator.mChildSize.getLastValue() - (F64)MemFootprint::measure(tracked) : -(F64)MemFootprint::measure(tracked)); } }; -- cgit v1.2.3 From 02dc270620bab6d3bd8035294af4be5b35894b1c Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 18 Sep 2013 17:08:34 -0700 Subject: BUILDFIX: bad merge --- indra/llcommon/lltrace.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 3cc0d16b93..3b4370f947 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -474,7 +474,7 @@ public: void operator delete[](void* ptr, size_t size) { - MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); accumulator.mAllocatedCount--; accumulator.mDeallocatedCount++; @@ -516,7 +516,7 @@ public: template AMOUNT_T& memClaimAmount(AMOUNT_T& size) { - MemStatAccumulator& accumulator = sMemStat.getPrimaryAccumulator(); + MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); mMemFootprint += (size_t)size; return size; } @@ -569,12 +569,12 @@ private: { static void claim(mem_trackable_t& tracker, TRACKED& tracked) { - accumulator.mChildSize.sample(accumulator.mChildSize.hasValue() ? accumulator.mChildSize.getLastValue() + (F64)MemFootprint::measure(tracked) : (F64)MemFootprint::measure(tracked)); + claim_shadow_mem( (F64)MemFootprint::measure(tracked)); } static void disclaim(mem_trackable_t& tracker, TRACKED& tracked) { - accumulator.mChildSize.sample(accumulator.mChildSize.hasValue() ? accumulator.mChildSize.getLastValue() - (F64)MemFootprint::measure(tracked) : -(F64)MemFootprint::measure(tracked)); + disclaim_shadow_mem((F64)MemFootprint::measure(tracked)); } }; }; -- cgit v1.2.3 From 0dfc08d22a21728ec670bd75e6fd0ed60c97bf06 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 19 Sep 2013 15:21:46 -0700 Subject: BUILDFIX: more bad merge stuff also added ability for statbar to show memtrackable info --- indra/llcommon/lltrace.h | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 3b4370f947..f677e4349e 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -512,12 +512,17 @@ public: return value; } + const size_t& memClaim(const size_t& size) + { + claim_mem(sMemStat, size); + mMemFootprint += size; + return size; + } - template - AMOUNT_T& memClaimAmount(AMOUNT_T& size) + size_t& memClaim(size_t& size) { - MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); - mMemFootprint += (size_t)size; + claim_mem(sMemStat, size); + mMemFootprint += size; return size; } @@ -536,10 +541,17 @@ public: return value; } - template - AMOUNT_T& memDisclaimAmount(AMOUNT_T& size) + const size_t& memDisclaim(const size_t& size) + { + disclaim_mem(sMemStat, size); + mMemFootprint -= size; + return size; + } + + size_t& memDisclaim(size_t& size) { - disclaim_mem(size); + disclaim_mem(sMemStat, size); + mMemFootprint -= size; return size; } -- cgit v1.2.3 From 448f5b42a071a88d5e3031538bcf60102c99af89 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 19 Sep 2013 16:36:55 -0700 Subject: BUILDFIX: bad calls to claim_shadow_mem and disclaim_shadow_mem --- indra/llcommon/lltrace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index f677e4349e..49ee252014 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -581,12 +581,12 @@ private: { static void claim(mem_trackable_t& tracker, TRACKED& tracked) { - claim_shadow_mem( (F64)MemFootprint::measure(tracked)); + claim_shadow_mem( sMemStat, MemFootprint::measure(tracked)); } static void disclaim(mem_trackable_t& tracker, TRACKED& tracked) { - disclaim_shadow_mem((F64)MemFootprint::measure(tracked)); + disclaim_shadow_mem(sMemStat, MemFootprint::measure(tracked)); } }; }; -- cgit v1.2.3 From 05ec5ca3d592ed7c730026582a2573d04c6e4c16 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 19 Sep 2013 20:05:53 -0700 Subject: BUILDFIX: forgot forward declaration better overrides for memclaim and memdisclaim of sizes added occlusion stats to stats floater stats now render range instead of mean --- indra/llcommon/lltrace.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 49ee252014..bf1119d694 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -512,14 +512,14 @@ public: return value; } - const size_t& memClaim(const size_t& size) + size_t& memClaim(size_t& size) { claim_mem(sMemStat, size); mMemFootprint += size; return size; } - size_t& memClaim(size_t& size) + int& memClaim(int& size) { claim_mem(sMemStat, size); mMemFootprint += size; @@ -541,14 +541,14 @@ public: return value; } - const size_t& memDisclaim(const size_t& size) + size_t& memDisclaim(size_t& size) { disclaim_mem(sMemStat, size); mMemFootprint -= size; return size; } - size_t& memDisclaim(size_t& size) + int& memDisclaim(int& size) { disclaim_mem(sMemStat, size); mMemFootprint -= size; -- cgit v1.2.3 From e25b5a359faaf4bb51186235567fcb1fea15e440 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 23 Sep 2013 16:07:32 -0700 Subject: refactored lltrace mem tracking to store allocation and deallocation sizes at the same time and work better with threads --- indra/llcommon/lltrace.h | 76 ++++++++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 29 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index bf1119d694..9c620ca5e3 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -200,7 +200,7 @@ void add(CountStatHandle& count, VALUE_T value) } template<> -class TraceType +class TraceType : public TraceType { public: @@ -211,7 +211,7 @@ public: }; template<> -class TraceType +class TraceType : public TraceType { public: @@ -221,6 +221,28 @@ public: {} }; +template<> +class TraceType + : public TraceType +{ +public: + + TraceType(const char* name, const char* description = "") + : TraceType(name, description) + {} +}; + +template<> +class TraceType + : public TraceType +{ +public: + + TraceType(const char* name, const char* description = "") + : TraceType(name, description) + {} +}; + template<> class TraceType : public TraceType @@ -248,59 +270,58 @@ public: /*virtual*/ const char* getUnitLabel() const { return "B"; } - TraceType& allocationCount() + TraceType& allocations() { - return static_cast&>(*(TraceType*)this); + return static_cast&>(*(TraceType*)this); } - TraceType& deallocationCount() + TraceType& deallocations() { - return static_cast&>(*(TraceType*)this); + return static_cast&>(*(TraceType*)this); } - TraceType& childMem() + TraceType& shadowAllocations() { - return static_cast&>(*(TraceType*)this); + return static_cast&>(*(TraceType*)this); } -}; -inline void track_alloc(MemStatHandle& measurement, size_t size) -{ - MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); - accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); - accumulator.mAllocatedCount++; -} + TraceType& shadowDeallocations() + { + return static_cast&>(*(TraceType*)this); + } -inline void track_dealloc(MemStatHandle& measurement, size_t size) -{ - MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); - accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); - accumulator.mAllocatedCount--; - accumulator.mDeallocatedCount++; -} + TraceType& shadowMem() + { + return static_cast&>(*(TraceType*)this); + } +}; inline void claim_mem(MemStatHandle& measurement, size_t size) { MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); + accumulator.mAllocated.add(1); } inline void disclaim_mem(MemStatHandle& measurement, size_t size) { MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); + accumulator.mDeallocated.add(1); } inline void claim_shadow_mem(MemStatHandle& measurement, size_t size) { MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mShadowSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); + accumulator.mShadowAllocated.add(1); } inline void disclaim_shadow_mem(MemStatHandle& measurement, size_t size) { MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mShadowSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); + accumulator.mShadowDeallocated.add(1); } // measures effective memory footprint of specified type @@ -408,7 +429,7 @@ public: void* operator new(size_t size) { - track_alloc(sMemStat, size); + claim_mem(sMemStat, size); if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) { @@ -430,7 +451,7 @@ public: void operator delete(void* ptr, size_t size) { - track_dealloc(sMemStat, size); + disclaim_mem(sMemStat, size); if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) { @@ -452,7 +473,7 @@ public: void *operator new [](size_t size) { - track_alloc(sMemStat, size); + claim_mem(sMemStat, size); if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) { @@ -474,10 +495,7 @@ public: void operator delete[](void* ptr, size_t size) { - MemStatAccumulator& accumulator = sMemStat.getCurrentAccumulator(); - accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); - accumulator.mAllocatedCount--; - accumulator.mDeallocatedCount++; + disclaim_mem(sMemStat, size); if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) { -- cgit v1.2.3 From ab8f64a96754edaa68dd1ff97b9519eff4496aa6 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 24 Sep 2013 00:05:43 -0700 Subject: converted memory tracking units to KB from B added more memory tracking to LLFolderView and kin --- indra/llcommon/lltrace.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 9c620ca5e3..5c833ea287 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -268,7 +268,7 @@ public: setKey(name); } - /*virtual*/ const char* getUnitLabel() const { return "B"; } + /*virtual*/ const char* getUnitLabel() const { return "KB"; } TraceType& allocations() { @@ -409,10 +409,12 @@ class MemTrackable typedef MemTrackable mem_trackable_t; static MemStatHandle sMemStat; + public: typedef void mem_trackable_tag_t; MemTrackable() + : mMemFootprint(0) { static bool name_initialized = false; if (!name_initialized) @@ -427,6 +429,11 @@ public: memDisclaim(mMemFootprint); } + static MemStatHandle& getMemStatHandle() + { + return sMemStat; + } + void* operator new(size_t size) { claim_mem(sMemStat, size); -- cgit v1.2.3 From 053d97db1b283ca2548dc1f64756ddfc5166158f Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 25 Sep 2013 19:12:35 -0700 Subject: better memory usage for LLTrace (tighter packing of recording arrays) removed complicated and unnecessary fast timer gapless handoff logic (it should be gapless anyway) improved MemTrackable API, better separation of shadow and footprint added memory usage stats to floater_stats.xml --- indra/llcommon/lltrace.h | 299 ++++++++++++++++++++--------------------------- 1 file changed, 128 insertions(+), 171 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 5c833ea287..355617a898 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -161,21 +161,6 @@ void sample(SampleStatHandle& measurement, VALUE_T value) measurement.getCurrentAccumulator().sample(storage_value(converted_value)); } -template -void add(SampleStatHandle& measurement, VALUE_T value) -{ - T converted_value(value); - SampleAccumulator& acc = measurement.getCurrentAccumulator(); - if (acc.hasValue()) - { - acc.sample(acc.getLastValue() + converted_value); - } - else - { - acc.sample(converted_value); - } -} - template class CountStatHandle : public TraceType @@ -296,28 +281,28 @@ public: } }; -inline void claim_mem(MemStatHandle& measurement, size_t size) +inline void claim_footprint(MemStatHandle& measurement, S32 size) { MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); accumulator.mAllocated.add(1); } -inline void disclaim_mem(MemStatHandle& measurement, size_t size) +inline void disclaim_footprint(MemStatHandle& measurement, S32 size) { MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); accumulator.mDeallocated.add(1); } -inline void claim_shadow_mem(MemStatHandle& measurement, size_t size) +inline void claim_shadow(MemStatHandle& measurement, S32 size) { MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mShadowSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); accumulator.mShadowAllocated.add(1); } -inline void disclaim_shadow_mem(MemStatHandle& measurement, size_t size) +inline void disclaim_shadow(MemStatHandle& measurement, S32 size) { MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mShadowSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); @@ -327,94 +312,122 @@ inline void disclaim_shadow_mem(MemStatHandle& measurement, size_t size) // measures effective memory footprint of specified type // specialize to cover different types -template -struct MemFootprint +template +struct MeasureMem { - static size_t measure(const T& value) + static size_t measureFootprint(const T& value) { return sizeof(T); } - static size_t measure() + static size_t measureFootprint() { return sizeof(T); } + + static size_t measureShadow(const T& value) + { + return 0; + } + + static size_t measureShadow() + { + return 0; + } }; template -struct MemFootprint +struct MeasureMem { - static size_t measure(const T* value) + static size_t measureFootprint(const T& value) + { + return sizeof(T) + value.getMemFootprint(); + } + + static size_t measureFootprint() + { + return sizeof(T); + } + + static size_t measureShadow(const T& value) + { + return value.getMemShadow(); + } + + static size_t measureShadow() + { + return MeasureMem::measureShadow(); + } +}; + + +template +struct MeasureMem +{ + static size_t measureFootprint(const T* value) { if (!value) { return 0; } - return MemFootprint::measure(*value); + return MeasureMem::measureFootprint(*value); } - static size_t measure() + static size_t measureFootprint() { - return MemFootprint::measure(); + return MeasureMem::measureFootprint(); } -}; -template -struct MemFootprint > -{ - static size_t measure(const std::basic_string& value) + static size_t measureShadow(const T* value) { - return value.capacity() * sizeof(T); + return MeasureMem::measureShadow(*value); } - static size_t measure() + static size_t measureShadow() { - return sizeof(std::basic_string); + return MeasureMem::measureShadow(); } }; -template -struct MemFootprint > +template +struct MeasureMem, IS_MEM_TRACKABLE> { - static size_t measure(const std::vector& value) + static size_t measureFootprint(const std::basic_string& value) { - return value.capacity() * MemFootprint::measure(); + return value.capacity() * sizeof(T); } - static size_t measure() + static size_t measureFootprint() { - return sizeof(std::vector); + return sizeof(std::basic_string); } -}; -template -struct MemFootprint > -{ - static size_t measure(const std::list& value) + static size_t measureShadow(const std::basic_string& value) { - return value.size() * (MemFootprint::measure() + sizeof(void*) * 2); + return 0; } - static size_t measure() + static size_t measureShadow() { - return sizeof(std::list); + return 0; } }; template class MemTrackable { - template - struct TrackMemImpl; - - typedef MemTrackable mem_trackable_t; - static MemStatHandle sMemStat; - public: typedef void mem_trackable_tag_t; + enum EMemType + { + MEM_FOOTPRINT, + MEM_SHADOW + }; + MemTrackable() - : mMemFootprint(0) + : mMemFootprint(0), + mMemShadow(0) { static bool name_initialized = false; if (!name_initialized) @@ -426,7 +439,8 @@ public: virtual ~MemTrackable() { - memDisclaim(mMemFootprint); + disclaimMem(mMemFootprint, MEM_FOOTPRINT); + disclaimMem(mMemShadow, MEM_SHADOW); } static MemStatHandle& getMemStatHandle() @@ -434,186 +448,129 @@ public: return sMemStat; } + S32 getMemFootprint() const { return mMemFootprint; } + S32 getMemShadow() const { return mMemShadow; } + void* operator new(size_t size) { - claim_mem(sMemStat, size); - - if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) - { - return ::operator new(size); - } - else if (ALIGNMENT == 16) - { - return ll_aligned_malloc_16(size); - } - else if (ALIGNMENT == 32) - { - return ll_aligned_malloc_32(size); - } - else - { - return ll_aligned_malloc(size, ALIGNMENT); - } + claim_footprint(sMemStat, size); + return ll_aligned_malloc(ALIGNMENT, size); } void operator delete(void* ptr, size_t size) { - disclaim_mem(sMemStat, size); - - if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) - { - ::operator delete(ptr); - } - else if (ALIGNMENT == 16) - { - ll_aligned_free_16(ptr); - } - else if (ALIGNMENT == 32) - { - return ll_aligned_free_32(ptr); - } - else - { - return ll_aligned_free(ptr); - } + disclaim_footprint(sMemStat, size); + ll_aligned_free(ALIGNMENT, ptr); } void *operator new [](size_t size) { - claim_mem(sMemStat, size); - - if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) - { - return ::operator new[](size); - } - else if (ALIGNMENT == 16) - { - return ll_aligned_malloc_16(size); - } - else if (ALIGNMENT == 32) - { - return ll_aligned_malloc_32(size); - } - else - { - return ll_aligned_malloc(size, ALIGNMENT); - } + claim_footprint(sMemStat, size); + return ll_aligned_malloc(ALIGNMENT, size); } void operator delete[](void* ptr, size_t size) { - disclaim_mem(sMemStat, size); - - if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) - { - ::operator delete[](ptr); - } - else if (ALIGNMENT == 16) - { - ll_aligned_free_16(ptr); - } - else if (ALIGNMENT == 32) - { - return ll_aligned_free_32(ptr); - } - else - { - return ll_aligned_free(ptr); - } + disclaim_footprint(sMemStat, size); + ll_aligned_free(ALIGNMENT, ptr); } // claim memory associated with other objects/data as our own, adding to our calculated footprint template - CLAIM_T& memClaim(CLAIM_T& value) + CLAIM_T& claimMem(CLAIM_T& value, EMemType mem_type = MEM_FOOTPRINT) { - TrackMemImpl::claim(*this, value); + trackAlloc(MeasureMem::measureFootprint(value), mem_type); + trackAlloc(MeasureMem::measureShadow(value), MEM_SHADOW); return value; } template - const CLAIM_T& memClaim(const CLAIM_T& value) + const CLAIM_T& claimMem(const CLAIM_T& value, EMemType mem_type = MEM_FOOTPRINT) { - TrackMemImpl::claim(*this, value); + trackAlloc(MeasureMem::measureFootprint(value), mem_type); + trackAlloc(MeasureMem::measureShadow(value), MEM_SHADOW); return value; } - size_t& memClaim(size_t& size) + size_t& claimMem(size_t& size, EMemType mem_type = MEM_FOOTPRINT) { - claim_mem(sMemStat, size); - mMemFootprint += size; + trackAlloc(size, mem_type); return size; } - int& memClaim(int& size) + S32& claimMem(S32& size, EMemType mem_type = MEM_FOOTPRINT) { - claim_mem(sMemStat, size); - mMemFootprint += size; + trackAlloc(size, mem_type); return size; } // remove memory we had claimed from our calculated footprint template - CLAIM_T& memDisclaim(CLAIM_T& value) + CLAIM_T& disclaimMem(CLAIM_T& value, EMemType mem_type = MEM_FOOTPRINT) { - TrackMemImpl::disclaim(*this, value); + trackDealloc(MeasureMem::measureFootprint(value), mem_type); + trackDealloc(MeasureMem::measureShadow(value), MEM_SHADOW); return value; } template - const CLAIM_T& memDisclaim(const CLAIM_T& value) + const CLAIM_T& disclaimMem(const CLAIM_T& value, EMemType mem_type = MEM_FOOTPRINT) { - TrackMemImpl::disclaim(*this, value); + trackDealloc(MeasureMem::measureFootprint(value), mem_type); + trackDealloc(MeasureMem::measureShadow(value), MEM_SHADOW); return value; } - size_t& memDisclaim(size_t& size) + size_t& disclaimMem(size_t& size, EMemType mem_type = MEM_FOOTPRINT) { - disclaim_mem(sMemStat, size); - mMemFootprint -= size; + trackDealloc(size, mem_type); return size; } - int& memDisclaim(int& size) + S32& disclaimMem(S32& size, EMemType mem_type = MEM_FOOTPRINT) { - disclaim_mem(sMemStat, size); - mMemFootprint -= size; + trackDealloc(size, mem_type); return size; } private: - size_t mMemFootprint; - template - struct TrackMemImpl + void trackAlloc(S32 size, EMemType mem_type) { - static void claim(mem_trackable_t& tracker, const TRACKED& tracked) + if (mem_type == MEM_FOOTPRINT) { - size_t footprint = MemFootprint::measure(tracked); - claim_mem(sMemStat, footprint); - tracker.mMemFootprint += footprint; + claim_footprint(sMemStat, size); + mMemFootprint += size; } - - static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked) + else { - size_t footprint = MemFootprint::measure(tracked); - disclaim_mem(sMemStat, footprint); - tracker.mMemFootprint -= footprint; + claim_shadow(sMemStat, size); + mMemShadow += size; } - }; + } - template - struct TrackMemImpl + void trackDealloc(S32 size, EMemType mem_type) { - static void claim(mem_trackable_t& tracker, TRACKED& tracked) + if (mem_type == MEM_FOOTPRINT) { - claim_shadow_mem( sMemStat, MemFootprint::measure(tracked)); + disclaim_footprint(sMemStat, size); + mMemFootprint -= size; } - - static void disclaim(mem_trackable_t& tracker, TRACKED& tracked) + else { - disclaim_shadow_mem(sMemStat, MemFootprint::measure(tracked)); + disclaim_shadow(sMemStat, size); + mMemShadow -= size; } - }; + } + +private: + // use signed values so that we can temporarily go negative + // and reconcile in destructor + // NB: this assumes that no single class is responsible for > 2GB of allocations + S32 mMemFootprint, + mMemShadow; + + static MemStatHandle sMemStat; }; template -- cgit v1.2.3 From af6b6db264aaa02e9e6a01d88233d129cf960fdf Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 27 Sep 2013 21:24:27 -0700 Subject: fixed lltrace memory tracking image memory utilization now always non-negative --- indra/llcommon/lltrace.h | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 355617a898..5c68bbbc0b 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -283,30 +283,34 @@ public: inline void claim_footprint(MemStatHandle& measurement, S32 size) { + if(size == 0) return; MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); - accumulator.mAllocated.add(1); + accumulator.mFootprintAllocations.record(size); } inline void disclaim_footprint(MemStatHandle& measurement, S32 size) { + if(size == 0) return; MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); - accumulator.mDeallocated.add(1); + accumulator.mFootprintDeallocations.add(size); } inline void claim_shadow(MemStatHandle& measurement, S32 size) { + if(size == 0) return; MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mShadowSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); - accumulator.mShadowAllocated.add(1); + accumulator.mShadowAllocations.record(size); } inline void disclaim_shadow(MemStatHandle& measurement, S32 size) { + if(size == 0) return; MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mShadowSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); - accumulator.mShadowDeallocated.add(1); + accumulator.mShadowDeallocations.add(size); } // measures effective memory footprint of specified type @@ -465,13 +469,13 @@ public: void *operator new [](size_t size) { - claim_footprint(sMemStat, size); + claim_footprint(sMemStat, size, true); return ll_aligned_malloc(ALIGNMENT, size); } void operator delete[](void* ptr, size_t size) { - disclaim_footprint(sMemStat, size); + disclaim_footprint(sMemStat, size, true); ll_aligned_free(ALIGNMENT, ptr); } -- cgit v1.2.3 From a96da325564f4e9769e85ad006f98a4ac08d4a47 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 27 Sep 2013 23:26:12 -0700 Subject: BUILDFIX: too many arguments --- indra/llcommon/lltrace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 5c68bbbc0b..da4bf6e36b 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -469,13 +469,13 @@ public: void *operator new [](size_t size) { - claim_footprint(sMemStat, size, true); + claim_footprint(sMemStat, size); return ll_aligned_malloc(ALIGNMENT, size); } void operator delete[](void* ptr, size_t size) { - disclaim_footprint(sMemStat, size, true); + disclaim_footprint(sMemStat, size); ll_aligned_free(ALIGNMENT, ptr); } -- cgit v1.2.3 From 12f0f8cb72f789e21b01b45063dcc5f1f5292087 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 1 Oct 2013 13:46:43 -0700 Subject: changed over to manual naming of MemTrackable stats changed claimMem and disclaimMem behavior to not pass through argument added more mem tracking stats to floater_stats --- indra/llcommon/lltrace.h | 298 +++++++++++------------------------------------ 1 file changed, 70 insertions(+), 228 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index da4bf6e36b..226f64d0c7 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -35,6 +35,8 @@ #include "lltraceaccumulators.h" #include "llthreadlocalstorage.h" #include "lltimer.h" +#include "llpointer.h" +#include "llunits.h" #include @@ -206,39 +208,6 @@ public: {} }; -template<> -class TraceType - : public TraceType -{ -public: - - TraceType(const char* name, const char* description = "") - : TraceType(name, description) - {} -}; - -template<> -class TraceType - : public TraceType -{ -public: - - TraceType(const char* name, const char* description = "") - : TraceType(name, description) - {} -}; - -template<> -class TraceType - : public TraceType -{ -public: - - TraceType(const char* name, const char* description = "") - : TraceType(name, description) - {} -}; - class MemStatHandle : public TraceType { public: @@ -264,109 +233,40 @@ public: { return static_cast&>(*(TraceType*)this); } - - TraceType& shadowAllocations() - { - return static_cast&>(*(TraceType*)this); - } - - TraceType& shadowDeallocations() - { - return static_cast&>(*(TraceType*)this); - } - - TraceType& shadowMem() - { - return static_cast&>(*(TraceType*)this); - } }; -inline void claim_footprint(MemStatHandle& measurement, S32 size) -{ - if(size == 0) return; - MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); - accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); - accumulator.mFootprintAllocations.record(size); -} - -inline void disclaim_footprint(MemStatHandle& measurement, S32 size) -{ - if(size == 0) return; - MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); - accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); - accumulator.mFootprintDeallocations.add(size); -} - -inline void claim_shadow(MemStatHandle& measurement, S32 size) -{ - if(size == 0) return; - MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); - accumulator.mShadowSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); - accumulator.mShadowAllocations.record(size); -} - -inline void disclaim_shadow(MemStatHandle& measurement, S32 size) -{ - if(size == 0) return; - MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); - accumulator.mShadowSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); - accumulator.mShadowDeallocations.add(size); -} // measures effective memory footprint of specified type // specialize to cover different types - -template +template struct MeasureMem { static size_t measureFootprint(const T& value) { return sizeof(T); } - - static size_t measureFootprint() - { - return sizeof(T); - } - - static size_t measureShadow(const T& value) - { - return 0; - } - - static size_t measureShadow() - { - return 0; - } }; -template -struct MeasureMem +template +struct MeasureMem { static size_t measureFootprint(const T& value) { return sizeof(T) + value.getMemFootprint(); } +}; - static size_t measureFootprint() - { - return sizeof(T); - } - - static size_t measureShadow(const T& value) - { - return value.getMemShadow(); - } - - static size_t measureShadow() +template +struct MeasureMem +{ + static size_t measureFootprint(const T& value) { - return MeasureMem::measureShadow(); + return U32Bytes(value).value(); } }; - -template -struct MeasureMem +template +struct MeasureMem { static size_t measureFootprint(const T* value) { @@ -376,46 +276,68 @@ struct MeasureMem } return MeasureMem::measureFootprint(*value); } +}; - static size_t measureFootprint() +template +struct MeasureMem, IS_MEM_TRACKABLE, IS_BYTES> +{ + static size_t measureFootprint(const LLPointer value) { - return MeasureMem::measureFootprint(); + if (value.isNull()) + { + return 0; + } + return MeasureMem::measureFootprint(*value); } +}; - static size_t measureShadow(const T* value) +template +struct MeasureMem +{ + static size_t measureFootprint(S32 value) { - return MeasureMem::measureShadow(*value); + return value; } +}; - static size_t measureShadow() +template +struct MeasureMem +{ + static size_t measureFootprint(U32 value) { - return MeasureMem::measureShadow(); + return value; } }; -template -struct MeasureMem, IS_MEM_TRACKABLE> +template +struct MeasureMem, IS_MEM_TRACKABLE, IS_BYTES> { static size_t measureFootprint(const std::basic_string& value) { return value.capacity() * sizeof(T); } +}; - static size_t measureFootprint() - { - return sizeof(std::basic_string); - } - static size_t measureShadow(const std::basic_string& value) - { - return 0; - } +template +inline void claim_footprint(MemStatHandle& measurement, const T& value) +{ + S32 size = MeasureMem::measureFootprint(value); + if(size == 0) return; + MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); + accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); + accumulator.mFootprintAllocations.record(size); +} - static size_t measureShadow() - { - return 0; - } -}; +template +inline void disclaim_footprint(MemStatHandle& measurement, const T& value) +{ + S32 size = MeasureMem::measureFootprint(value); + if(size == 0) return; + MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); + accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); + accumulator.mFootprintDeallocations.add(size); +} template class MemTrackable @@ -423,28 +345,20 @@ class MemTrackable public: typedef void mem_trackable_tag_t; - enum EMemType - { - MEM_FOOTPRINT, - MEM_SHADOW - }; - - MemTrackable() - : mMemFootprint(0), - mMemShadow(0) + MemTrackable(const char* name) + : mMemFootprint(0) { static bool name_initialized = false; if (!name_initialized) { name_initialized = true; - sMemStat.setName(typeid(DERIVED).name()); + sMemStat.setName(name); } } virtual ~MemTrackable() { - disclaimMem(mMemFootprint, MEM_FOOTPRINT); - disclaimMem(mMemShadow, MEM_SHADOW); + disclaimMem(mMemFootprint); } static MemStatHandle& getMemStatHandle() @@ -453,7 +367,6 @@ public: } S32 getMemFootprint() const { return mMemFootprint; } - S32 getMemShadow() const { return mMemShadow; } void* operator new(size_t size) { @@ -467,7 +380,7 @@ public: ll_aligned_free(ALIGNMENT, ptr); } - void *operator new [](size_t size) + void* operator new [](size_t size) { claim_footprint(sMemStat, size); return ll_aligned_malloc(ALIGNMENT, size); @@ -481,98 +394,27 @@ public: // claim memory associated with other objects/data as our own, adding to our calculated footprint template - CLAIM_T& claimMem(CLAIM_T& value, EMemType mem_type = MEM_FOOTPRINT) - { - trackAlloc(MeasureMem::measureFootprint(value), mem_type); - trackAlloc(MeasureMem::measureShadow(value), MEM_SHADOW); - return value; - } - - template - const CLAIM_T& claimMem(const CLAIM_T& value, EMemType mem_type = MEM_FOOTPRINT) - { - trackAlloc(MeasureMem::measureFootprint(value), mem_type); - trackAlloc(MeasureMem::measureShadow(value), MEM_SHADOW); - return value; - } - - size_t& claimMem(size_t& size, EMemType mem_type = MEM_FOOTPRINT) - { - trackAlloc(size, mem_type); - return size; - } - - S32& claimMem(S32& size, EMemType mem_type = MEM_FOOTPRINT) + void claimMem(const CLAIM_T& value) const { - trackAlloc(size, mem_type); - return size; + S32 size = MeasureMem::measureFootprint(value); + claim_footprint(sMemStat, size); + mMemFootprint += size; } // remove memory we had claimed from our calculated footprint template - CLAIM_T& disclaimMem(CLAIM_T& value, EMemType mem_type = MEM_FOOTPRINT) - { - trackDealloc(MeasureMem::measureFootprint(value), mem_type); - trackDealloc(MeasureMem::measureShadow(value), MEM_SHADOW); - return value; - } - - template - const CLAIM_T& disclaimMem(const CLAIM_T& value, EMemType mem_type = MEM_FOOTPRINT) - { - trackDealloc(MeasureMem::measureFootprint(value), mem_type); - trackDealloc(MeasureMem::measureShadow(value), MEM_SHADOW); - return value; - } - - size_t& disclaimMem(size_t& size, EMemType mem_type = MEM_FOOTPRINT) + void disclaimMem(const CLAIM_T& value) const { - trackDealloc(size, mem_type); - return size; - } - - S32& disclaimMem(S32& size, EMemType mem_type = MEM_FOOTPRINT) - { - trackDealloc(size, mem_type); - return size; - } - -private: - - void trackAlloc(S32 size, EMemType mem_type) - { - if (mem_type == MEM_FOOTPRINT) - { - claim_footprint(sMemStat, size); - mMemFootprint += size; - } - else - { - claim_shadow(sMemStat, size); - mMemShadow += size; - } - } - - void trackDealloc(S32 size, EMemType mem_type) - { - if (mem_type == MEM_FOOTPRINT) - { - disclaim_footprint(sMemStat, size); - mMemFootprint -= size; - } - else - { - disclaim_shadow(sMemStat, size); - mMemShadow -= size; - } + S32 size = MeasureMem::measureFootprint(value); + disclaim_footprint(sMemStat, size); + mMemFootprint -= size; } private: // use signed values so that we can temporarily go negative // and reconcile in destructor // NB: this assumes that no single class is responsible for > 2GB of allocations - S32 mMemFootprint, - mMemShadow; + mutable S32 mMemFootprint; static MemStatHandle sMemStat; }; -- cgit v1.2.3 From 754e8752a9b9a2e75d425a10cb8a0a6f85ad4bf5 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 3 Oct 2013 14:30:34 -0700 Subject: added initial memory usage tracking for lltrace --- indra/llcommon/lltrace.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 226f64d0c7..421ec3bda5 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -320,7 +320,7 @@ struct MeasureMem, IS_MEM_TRACKABLE, IS_BYTES> template -inline void claim_footprint(MemStatHandle& measurement, const T& value) +inline void claim_alloc(MemStatHandle& measurement, const T& value) { S32 size = MeasureMem::measureFootprint(value); if(size == 0) return; @@ -330,7 +330,7 @@ inline void claim_footprint(MemStatHandle& measurement, const T& value) } template -inline void disclaim_footprint(MemStatHandle& measurement, const T& value) +inline void disclaim_alloc(MemStatHandle& measurement, const T& value) { S32 size = MeasureMem::measureFootprint(value); if(size == 0) return; @@ -370,25 +370,25 @@ public: void* operator new(size_t size) { - claim_footprint(sMemStat, size); + claim_alloc(sMemStat, size); return ll_aligned_malloc(ALIGNMENT, size); } void operator delete(void* ptr, size_t size) { - disclaim_footprint(sMemStat, size); + disclaim_alloc(sMemStat, size); ll_aligned_free(ALIGNMENT, ptr); } void* operator new [](size_t size) { - claim_footprint(sMemStat, size); + claim_alloc(sMemStat, size); return ll_aligned_malloc(ALIGNMENT, size); } void operator delete[](void* ptr, size_t size) { - disclaim_footprint(sMemStat, size); + disclaim_alloc(sMemStat, size); ll_aligned_free(ALIGNMENT, ptr); } @@ -397,7 +397,7 @@ public: void claimMem(const CLAIM_T& value) const { S32 size = MeasureMem::measureFootprint(value); - claim_footprint(sMemStat, size); + claim_alloc(sMemStat, size); mMemFootprint += size; } @@ -406,7 +406,7 @@ public: void disclaimMem(const CLAIM_T& value) const { S32 size = MeasureMem::measureFootprint(value); - disclaim_footprint(sMemStat, size); + disclaim_alloc(sMemStat, size); mMemFootprint -= size; } -- cgit v1.2.3 From f8a85003ddd4bee1ae00fc329c1c1d66d6100cbd Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 3 Oct 2013 19:04:51 -0700 Subject: more memory optimizations of lltrace --- indra/llcommon/lltrace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 421ec3bda5..3dc2e5248f 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -326,7 +326,7 @@ inline void claim_alloc(MemStatHandle& measurement, const T& value) if(size == 0) return; MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); - accumulator.mFootprintAllocations.record(size); + accumulator.mAllocations.record(size); } template @@ -336,7 +336,7 @@ inline void disclaim_alloc(MemStatHandle& measurement, const T& value) if(size == 0) return; MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); - accumulator.mFootprintDeallocations.add(size); + accumulator.mDeallocations.add(size); } template -- cgit v1.2.3 From 17df8988fec3f2ba991ca9e34ff8148253a2fc04 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 7 Oct 2013 13:38:03 -0700 Subject: renamed TraceType to StatType added more MemTrackable types optimized memory usage of LLTrace some more --- indra/llcommon/lltrace.h | 127 ++++++++++++++++++++++++++++------------------- 1 file changed, 77 insertions(+), 50 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 3dc2e5248f..325112b9b1 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -38,8 +38,6 @@ #include "llpointer.h" #include "llunits.h" -#include - namespace LLTrace { class Recording; @@ -53,11 +51,11 @@ STORAGE_TYPE storage_value(LLUnit val) { return val.val template STORAGE_TYPE storage_value(LLUnitImplicit val) { return val.value(); } -class TraceBase +class StatBase { public: - TraceBase(const char* name, const char* description); - virtual ~TraceBase() {}; + StatBase(const char* name, const char* description); + virtual ~StatBase() {}; virtual const char* getUnitLabel() const; const std::string& getName() const { return mName; } @@ -69,14 +67,14 @@ protected: }; template -class TraceType -: public TraceBase, - public LLInstanceTracker, std::string> +class StatType +: public StatBase, + public LLInstanceTracker, std::string> { public: - TraceType(const char* name, const char* description = NULL) - : LLInstanceTracker, std::string>(name), - TraceBase(name, description), + StatType(const char* name, const char* description = NULL) + : LLInstanceTracker, std::string>(name), + StatBase(name, description), mAccumulatorIndex(AccumulatorBuffer::getDefaultBuffer()->reserveSlot()) {} @@ -95,38 +93,38 @@ protected: template<> -class TraceType -: public TraceType +class StatType +: public StatType { public: - TraceType(const char* name, const char* description = "") - : TraceType(name, description) + StatType(const char* name, const char* description = "") + : StatType(name, description) {} }; template<> -class TraceType - : public TraceType +class StatType + : public StatType { public: - TraceType(const char* name, const char* description = "") - : TraceType(name, description) + StatType(const char* name, const char* description = "") + : StatType(name, description) {} }; template class EventStatHandle -: public TraceType +: public StatType { public: typedef F64 storage_t; - typedef TraceType trace_t; + typedef StatType stat_t; typedef EventStatHandle self_t; EventStatHandle(const char* name, const char* description = NULL) - : trace_t(name, description) + : stat_t(name, description) {} /*virtual*/ const char* getUnitLabel() const { return LLGetUnitLabel::getUnitLabel(); } @@ -142,15 +140,15 @@ void record(EventStatHandle& measurement, VALUE_T value) template class SampleStatHandle -: public TraceType +: public StatType { public: typedef F64 storage_t; - typedef TraceType trace_t; + typedef StatType stat_t; typedef SampleStatHandle self_t; SampleStatHandle(const char* name, const char* description = NULL) - : trace_t(name, description) + : stat_t(name, description) {} /*virtual*/ const char* getUnitLabel() const { return LLGetUnitLabel::getUnitLabel(); } @@ -165,15 +163,15 @@ void sample(SampleStatHandle& measurement, VALUE_T value) template class CountStatHandle -: public TraceType +: public StatType { public: typedef F64 storage_t; - typedef TraceType trace_t; + typedef StatType stat_t; typedef CountStatHandle self_t; CountStatHandle(const char* name, const char* description = NULL) - : trace_t(name, description) + : stat_t(name, description) {} /*virtual*/ const char* getUnitLabel() const { return LLGetUnitLabel::getUnitLabel(); } @@ -187,34 +185,36 @@ void add(CountStatHandle& count, VALUE_T value) } template<> -class TraceType -: public TraceType +class StatType +: public StatType { public: - TraceType(const char* name, const char* description = "") - : TraceType(name, description) + StatType(const char* name, const char* description = "") + : StatType(name, description) {} }; template<> -class TraceType -: public TraceType +class StatType +: public StatType { public: - TraceType(const char* name, const char* description = "") - : TraceType(name, description) + StatType(const char* name, const char* description = "") + : StatType(name, description) {} }; -class MemStatHandle : public TraceType +class MemStatHandle : public StatType { public: - typedef TraceType trace_t; + typedef StatType stat_t; MemStatHandle(const char* name) - : trace_t(name) - {} + : stat_t(name) + { + mName = name; + } void setName(const char* name) { @@ -224,14 +224,14 @@ public: /*virtual*/ const char* getUnitLabel() const { return "KB"; } - TraceType& allocations() + StatType& allocations() { - return static_cast&>(*(TraceType*)this); + return static_cast&>(*(StatType*)this); } - TraceType& deallocations() + StatType& deallocations() { - return static_cast&>(*(TraceType*)this); + return static_cast&>(*(StatType*)this); } }; @@ -324,7 +324,7 @@ inline void claim_alloc(MemStatHandle& measurement, const T& value) { S32 size = MeasureMem::measureFootprint(value); if(size == 0) return; - MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); + MemAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); accumulator.mAllocations.record(size); } @@ -334,18 +334,18 @@ inline void disclaim_alloc(MemStatHandle& measurement, const T& value) { S32 size = MeasureMem::measureFootprint(value); if(size == 0) return; - MemStatAccumulator& accumulator = measurement.getCurrentAccumulator(); + MemAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); accumulator.mDeallocations.add(size); } template -class MemTrackable +class MemTrackableNonVirtual { public: typedef void mem_trackable_tag_t; - MemTrackable(const char* name) + MemTrackableNonVirtual(const char* name) : mMemFootprint(0) { static bool name_initialized = false; @@ -356,7 +356,7 @@ public: } } - virtual ~MemTrackable() + ~MemTrackableNonVirtual() { disclaimMem(mMemFootprint); } @@ -374,12 +374,27 @@ public: return ll_aligned_malloc(ALIGNMENT, size); } + template + static void* aligned_new(size_t size) + { + claim_alloc(sMemStat, size); + return ll_aligned_malloc(CUSTOM_ALIGNMENT, size); + } + void operator delete(void* ptr, size_t size) { disclaim_alloc(sMemStat, size); ll_aligned_free(ALIGNMENT, ptr); } + template + static void aligned_delete(void* ptr, size_t size) + { + disclaim_alloc(sMemStat, size); + ll_aligned_free(CUSTOM_ALIGNMENT, ptr); + } + + void* operator new [](size_t size) { claim_alloc(sMemStat, size); @@ -420,7 +435,19 @@ private: }; template -MemStatHandle MemTrackable::sMemStat(""); +MemStatHandle MemTrackableNonVirtual::sMemStat(typeid(MemTrackableNonVirtual).name()); +template +class MemTrackable : public MemTrackableNonVirtual +{ +public: + MemTrackable(const char* name) + : MemTrackableNonVirtual(name) + {} + + virtual ~MemTrackable() + {} +}; } + #endif // LL_LLTRACE_H -- cgit v1.2.3 From 1acceb3633c0f0c4fdf29b17d77d67c8a9b71986 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 14 Oct 2013 10:18:41 -0700 Subject: changed ll_aligned_(malloc|free) to take alignment size as a template argument --- indra/llcommon/lltrace.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 325112b9b1..2f4390e4d1 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -371,40 +371,40 @@ public: void* operator new(size_t size) { claim_alloc(sMemStat, size); - return ll_aligned_malloc(ALIGNMENT, size); + return ll_aligned_malloc(size); } template static void* aligned_new(size_t size) { claim_alloc(sMemStat, size); - return ll_aligned_malloc(CUSTOM_ALIGNMENT, size); + return ll_aligned_malloc(size); } void operator delete(void* ptr, size_t size) { disclaim_alloc(sMemStat, size); - ll_aligned_free(ALIGNMENT, ptr); + ll_aligned_free(ptr); } template static void aligned_delete(void* ptr, size_t size) { disclaim_alloc(sMemStat, size); - ll_aligned_free(CUSTOM_ALIGNMENT, ptr); + ll_aligned_free(ptr); } void* operator new [](size_t size) { claim_alloc(sMemStat, size); - return ll_aligned_malloc(ALIGNMENT, size); + return ll_aligned_malloc(size); } void operator delete[](void* ptr, size_t size) { disclaim_alloc(sMemStat, size); - ll_aligned_free(ALIGNMENT, ptr); + ll_aligned_free(ptr); } // claim memory associated with other objects/data as our own, adding to our calculated footprint -- cgit v1.2.3 From 697d2e720ba75e142a4d56ae8794bab8d7698dad Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 15 Oct 2013 20:24:42 -0700 Subject: renamed TimeBlock to BlockTimerStatHandle --- indra/llcommon/lltrace.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 2f4390e4d1..cbdf4e4a6f 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -72,7 +72,7 @@ class StatType public LLInstanceTracker, std::string> { public: - StatType(const char* name, const char* description = NULL) + StatType(const char* name, const char* description) : LLInstanceTracker, std::string>(name), StatBase(name, description), mAccumulatorIndex(AccumulatorBuffer::getDefaultBuffer()->reserveSlot()) @@ -210,8 +210,8 @@ class MemStatHandle : public StatType { public: typedef StatType stat_t; - MemStatHandle(const char* name) - : stat_t(name) + MemStatHandle(const char* name, const char* description = "") + : stat_t(name, description) { mName = name; } -- cgit v1.2.3 From 1beaedacadc8093c9df612992a873f9c89354bce Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 17 Oct 2013 14:23:56 -0700 Subject: moved root timer to global variable added flag to LLInstanceTracker to allow multiple values per key made StatType allow multiple values per key to eliminate block timer related crash --- indra/llcommon/lltrace.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index cbdf4e4a6f..b499036af2 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -69,11 +69,12 @@ protected: template class StatType : public StatBase, - public LLInstanceTracker, std::string> + public LLInstanceTracker, std::string, InstanceTrackerAllowKeyCollisions> { public: + typedef LLInstanceTracker, std::string, InstanceTrackerAllowKeyCollisions> instance_tracker_t; StatType(const char* name, const char* description) - : LLInstanceTracker, std::string>(name), + : instance_tracker_t(name), StatBase(name, description), mAccumulatorIndex(AccumulatorBuffer::getDefaultBuffer()->reserveSlot()) {} -- cgit v1.2.3 From dc60a7564abf16cbf269e47cfc33ed00c6bb0870 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 24 Oct 2013 14:37:57 -0700 Subject: SH-4577 WIP Interesting: viewer crashed when clicking a offline Conversation containing a shared object potential fix by making instance tracker allow key collisions for LLToastNotifyPanel changed assertion macro to use original unpreprocessed source code renamed instance tracker behavior macros to use LL prefix added RestoreCameraPosOnLogin setting to optionally restore old camera positioning behavior --- indra/llcommon/lltrace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index b499036af2..8b67dd8f44 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -69,10 +69,10 @@ protected: template class StatType : public StatBase, - public LLInstanceTracker, std::string, InstanceTrackerAllowKeyCollisions> + public LLInstanceTracker, std::string, LLInstanceTrackerAllowKeyCollisions> { public: - typedef LLInstanceTracker, std::string, InstanceTrackerAllowKeyCollisions> instance_tracker_t; + typedef LLInstanceTracker, std::string, LLInstanceTrackerAllowKeyCollisions> instance_tracker_t; StatType(const char* name, const char* description) : instance_tracker_t(name), StatBase(name, description), -- cgit v1.2.3 From 391ac367d6922f30bf3a186bc15e1fc38366eecf Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 19 Nov 2013 17:40:44 -0800 Subject: SH-4634 FIX Interesting: Viewer crashes when receiving teleport offer renamed fast timers to have unique names, changes instance tracker to never allow duplicates --- indra/llcommon/lltrace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 8b67dd8f44..7e811efe71 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -69,10 +69,10 @@ protected: template class StatType : public StatBase, - public LLInstanceTracker, std::string, LLInstanceTrackerAllowKeyCollisions> + public LLInstanceTracker, std::string> { public: - typedef LLInstanceTracker, std::string, LLInstanceTrackerAllowKeyCollisions> instance_tracker_t; + typedef LLInstanceTracker, std::string> instance_tracker_t; StatType(const char* name, const char* description) : instance_tracker_t(name), StatBase(name, description), -- cgit v1.2.3 From 3040b429a3b136b87ddb0ae88ccfa3a7aa71e232 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 6 Feb 2014 11:27:16 -0800 Subject: added LL_TRACE_ENABLED to allow disabling of lltrace --- indra/llcommon/lltrace.h | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'indra/llcommon/lltrace.h') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 7e811efe71..5f1289dad8 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -38,6 +38,8 @@ #include "llpointer.h" #include "llunits.h" +#define LL_TRACE_ENABLED 1 + namespace LLTrace { class Recording; @@ -135,8 +137,10 @@ public: template void record(EventStatHandle& measurement, VALUE_T value) { +#if LL_TRACE_ENABLED T converted_value(value); measurement.getCurrentAccumulator().record(storage_value(converted_value)); +#endif } template @@ -158,8 +162,10 @@ public: template void sample(SampleStatHandle& measurement, VALUE_T value) { +#if LL_TRACE_ENABLED T converted_value(value); measurement.getCurrentAccumulator().sample(storage_value(converted_value)); +#endif } template @@ -181,8 +187,10 @@ public: template void add(CountStatHandle& count, VALUE_T value) { +#if LL_TRACE_ENABLED T converted_value(value); count.getCurrentAccumulator().add(storage_value(converted_value)); +#endif } template<> @@ -323,21 +331,25 @@ struct MeasureMem, IS_MEM_TRACKABLE, IS_BYTES> template inline void claim_alloc(MemStatHandle& measurement, const T& value) { +#if LL_TRACE_ENABLED S32 size = MeasureMem::measureFootprint(value); if(size == 0) return; MemAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); accumulator.mAllocations.record(size); +#endif } template inline void disclaim_alloc(MemStatHandle& measurement, const T& value) { +#if LL_TRACE_ENABLED S32 size = MeasureMem::measureFootprint(value); if(size == 0) return; MemAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); accumulator.mDeallocations.add(size); +#endif } template @@ -347,16 +359,21 @@ public: typedef void mem_trackable_tag_t; MemTrackableNonVirtual(const char* name) +#if LL_TRACE_ENABLED : mMemFootprint(0) +#endif { +#if LL_TRACE_ENABLED static bool name_initialized = false; if (!name_initialized) { name_initialized = true; sMemStat.setName(name); } +#endif } +#if LL_TRACE_ENABLED ~MemTrackableNonVirtual() { disclaimMem(mMemFootprint); @@ -368,43 +385,55 @@ public: } S32 getMemFootprint() const { return mMemFootprint; } +#endif void* operator new(size_t size) { +#if LL_TRACE_ENABLED claim_alloc(sMemStat, size); +#endif return ll_aligned_malloc(size); } template static void* aligned_new(size_t size) { +#if LL_TRACE_ENABLED claim_alloc(sMemStat, size); +#endif return ll_aligned_malloc(size); } void operator delete(void* ptr, size_t size) { +#if LL_TRACE_ENABLED disclaim_alloc(sMemStat, size); +#endif ll_aligned_free(ptr); } template static void aligned_delete(void* ptr, size_t size) { +#if LL_TRACE_ENABLED disclaim_alloc(sMemStat, size); +#endif ll_aligned_free(ptr); } - void* operator new [](size_t size) { +#if LL_TRACE_ENABLED claim_alloc(sMemStat, size); +#endif return ll_aligned_malloc(size); } void operator delete[](void* ptr, size_t size) { +#if LL_TRACE_ENABLED disclaim_alloc(sMemStat, size); +#endif ll_aligned_free(ptr); } @@ -412,31 +441,40 @@ public: template void claimMem(const CLAIM_T& value) const { +#if LL_TRACE_ENABLED S32 size = MeasureMem::measureFootprint(value); claim_alloc(sMemStat, size); mMemFootprint += size; +#endif } // remove memory we had claimed from our calculated footprint template void disclaimMem(const CLAIM_T& value) const { +#if LL_TRACE_ENABLED S32 size = MeasureMem::measureFootprint(value); disclaim_alloc(sMemStat, size); mMemFootprint -= size; +#endif } private: +#if LL_TRACE_ENABLED // use signed values so that we can temporarily go negative // and reconcile in destructor // NB: this assumes that no single class is responsible for > 2GB of allocations mutable S32 mMemFootprint; static MemStatHandle sMemStat; +#endif + }; +#if LL_TRACE_ENABLED template MemStatHandle MemTrackableNonVirtual::sMemStat(typeid(MemTrackableNonVirtual).name()); +#endif template class MemTrackable : public MemTrackableNonVirtual -- cgit v1.2.3