From a74b5dfa923f8eeccc9b786143f0f832de3ad450 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Tue, 4 Jun 2013 19:45:33 -0700
Subject: [PATCH] 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/llfasttimer.h        |  12 +--
 indra/llcommon/lltrace.h            | 143 +++++++++++++++++++++-------
 indra/llcommon/lltracerecording.cpp |  74 ++++++++++++--
 indra/llcommon/lltracerecording.h   |  36 ++++---
 indra/llcommon/llunit.h             |  59 +++++-------
 indra/llimage/llimage.cpp           |  12 +--
 indra/newview/llscenemonitor.cpp    |  16 +++-
 indra/newview/lltextureview.cpp     |  12 +--
 indra/newview/llviewerstats.cpp     |   8 +-
 indra/newview/llviewerstats.h       |   2 +-
 indra/newview/llviewertexture.cpp   |   8 +-
 indra/newview/llviewertexture.h     |   8 +-
 indra/newview/llviewerwindow.cpp    |   2 +-
 13 files changed, 265 insertions(+), 127 deletions(-)

diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index 32a0629a87f..f329b30472d 100644
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -101,14 +101,14 @@ class TimeBlock
 	void setCollapsed(bool collapsed)	{ mCollapsed = collapsed; }
 	bool getCollapsed() const			{ return mCollapsed; }
 
-	TraceType<TimeBlockAccumulator::CallCountAspect>& callCount() 
+	TraceType<TimeBlockAccumulator::CallCountFacet>& callCount() 
 	{ 
-		return static_cast<TraceType<TimeBlockAccumulator::CallCountAspect>&>(*(TraceType<TimeBlockAccumulator>*)this);
+		return static_cast<TraceType<TimeBlockAccumulator::CallCountFacet>&>(*(TraceType<TimeBlockAccumulator>*)this);
 	}
 
-	TraceType<TimeBlockAccumulator::SelfTimeAspect>& selfTime() 
+	TraceType<TimeBlockAccumulator::SelfTimeFacet>& selfTime() 
 	{ 
-		return static_cast<TraceType<TimeBlockAccumulator::SelfTimeAspect>&>(*(TraceType<TimeBlockAccumulator>*)this);
+		return static_cast<TraceType<TimeBlockAccumulator::SelfTimeFacet>&>(*(TraceType<TimeBlockAccumulator>*)this);
 	}
 
 	static TimeBlock& getRootTimeBlock();
@@ -277,8 +277,6 @@ class TimeBlock
 LL_FORCE_INLINE BlockTimer::BlockTimer(TimeBlock& timer)
 {
 #if FAST_TIMER_ON
-	mStartTime = TimeBlock::getCPUClockCount64();
-
 	BlockTimerStackRecord* cur_timer_data = ThreadTimerStack::getIfExists();
 	TimeBlockAccumulator* accumulator = timer.getPrimaryAccumulator();
 	accumulator->mActiveCount++;
@@ -292,6 +290,8 @@ LL_FORCE_INLINE BlockTimer::BlockTimer(TimeBlock& timer)
 	cur_timer_data->mActiveTimer = this;
 	cur_timer_data->mTimeBlock = &timer;
 	cur_timer_data->mChildTime = 0;
+
+	mStartTime = TimeBlock::getCPUClockCount64();
 #endif
 }
 
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index 2953e993d41..37196d9f63e 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -46,13 +46,13 @@ namespace LLTrace
 class Recording;
 
 typedef LLUnit<LLUnits::Bytes, F64>			Bytes;
-typedef LLUnit<LLUnits::Kilobytes, F64>		Kilobytes;
-typedef LLUnit<LLUnits::Megabytes, F64>		Megabytes;
-typedef LLUnit<LLUnits::Gigabytes, F64>		Gigabytes;
+typedef LLUnit<LLUnits::Kibibytes, F64>		Kibibytes;
+typedef LLUnit<LLUnits::Mibibytes, F64>		Mibibytes;
+typedef LLUnit<LLUnits::Gibibytes, F64>		Gibibytes;
 typedef LLUnit<LLUnits::Bits, F64>			Bits;
-typedef LLUnit<LLUnits::Kilobits, F64>		Kilobits;
-typedef LLUnit<LLUnits::Megabits, F64>		Megabits;
-typedef LLUnit<LLUnits::Gigabits, F64>		Gigabits;
+typedef LLUnit<LLUnits::Kibibits, F64>		Kibibits;
+typedef LLUnit<LLUnits::Mibibits, F64>		Mibibits;
+typedef LLUnit<LLUnits::Gibibits, F64>		Gibibits;
 
 typedef LLUnit<LLUnits::Seconds, F64>		Seconds;
 typedef LLUnit<LLUnits::Milliseconds, F64>	Milliseconds;
@@ -583,14 +583,14 @@ class TimeBlockAccumulator
 	typedef LLUnit<LLUnits::Seconds, F64> 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<LLUnits::Seconds, F64> value_t;
 		typedef LLUnit<LLUnits::Seconds, F64> mean_t;
@@ -616,7 +616,7 @@ class TimeBlockAccumulator
 };
 
 template<>
-class TraceType<TimeBlockAccumulator::CallCountAspect>
+class TraceType<TimeBlockAccumulator::CallCountFacet>
 :	public TraceType<TimeBlockAccumulator>
 {
 public:
@@ -627,7 +627,7 @@ class TraceType<TimeBlockAccumulator::CallCountAspect>
 };
 
 template<>
-class TraceType<TimeBlockAccumulator::SelfTimeAspect>
+class TraceType<TimeBlockAccumulator::SelfTimeFacet>
 	:	public TraceType<TimeBlockAccumulator>
 {
 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<LLUnits::Bytes, F64> value_t;
+		typedef LLUnit<LLUnits::Bytes, F64> 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<MemStatAccumulator::AllocationCountFacet>
+:	public TraceType<MemStatAccumulator>
+{
+public:
+
+	TraceType(const char* name, const char* description = "")
+	:	TraceType<MemStatAccumulator>(name, description)
+	{}
+};
 
-	size_t		mSize,
-				mChildSize;
-	int			mAllocatedCount,
-				mDeallocatedCount;
+template<>
+class TraceType<MemStatAccumulator::DeallocationCountFacet>
+:	public TraceType<MemStatAccumulator>
+{
+public:
+
+	TraceType(const char* name, const char* description = "")
+	:	TraceType<MemStatAccumulator>(name, description)
+	{}
+};
+
+template<>
+class TraceType<MemStatAccumulator::ChildMemFacet>
+	:	public TraceType<MemStatAccumulator>
+{
+public:
+
+	TraceType(const char* name, const char* description = "")
+		:	TraceType<MemStatAccumulator>(name, description)
+	{}
 };
 
 class MemStatHandle : public TraceType<MemStatAccumulator>
@@ -765,6 +820,21 @@ class MemStatHandle : public TraceType<MemStatAccumulator>
 	{}
 
 	/*virtual*/ const char* getUnitLabel() { return "B"; }
+
+	TraceType<MemStatAccumulator::AllocationCountFacet>& allocationCount() 
+	{ 
+		return static_cast<TraceType<MemStatAccumulator::AllocationCountFacet>&>(*(TraceType<MemStatAccumulator>*)this);
+	}
+
+	TraceType<MemStatAccumulator::DeallocationCountFacet>& deallocationCount() 
+	{ 
+		return static_cast<TraceType<MemStatAccumulator::DeallocationCountFacet>&>(*(TraceType<MemStatAccumulator>*)this);
+	}
+
+	TraceType<MemStatAccumulator::ChildMemFacet>& childMem() 
+	{ 
+		return static_cast<TraceType<MemStatAccumulator::ChildMemFacet>&>(*(TraceType<MemStatAccumulator>*)this);
+	}
 };
 
 // measures effective memory footprint of specified type
@@ -865,7 +935,7 @@ class MemTrackable
 		MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
 		if (accumulator)
 		{
-			accumulator->mSize += size;
+			accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size);
 			accumulator->mAllocatedCount++;
 		}
 
@@ -877,7 +947,7 @@ class MemTrackable
 		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 @@ class MemTrackable
 		MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
 		if (accumulator)
 		{
-			accumulator->mSize += size;
+			accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size);
 			accumulator->mAllocatedCount++;
 		}
 
@@ -901,7 +971,7 @@ class MemTrackable
 		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 @@ class MemTrackable
 	}
 
 
-	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 @@ class MemTrackable
 		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 @@ class MemTrackable
 			if (accumulator)
 			{
 				size_t footprint = MemFootprint<TRACKED>::measure(tracked);
-				accumulator->mSize += footprint;
+				accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)footprint);
 				tracker.mMemFootprint += footprint;
 			}
 		}
@@ -982,7 +1051,7 @@ class MemTrackable
 			if (accumulator)
 			{
 				size_t footprint = MemFootprint<TRACKED>::measure(tracked);
-				accumulator->mSize -= footprint;
+				accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)footprint);
 				tracker.mMemFootprint -= footprint;
 			}
 		}
@@ -996,7 +1065,7 @@ class MemTrackable
 			MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
 			if (accumulator)
 			{
-				accumulator->mChildSize += MemFootprint<TRACKED>::measure(tracked);
+				accumulator->mChildSize.sample(accumulator->mChildSize.getLastValue() + (F64)MemFootprint<TRACKED>::measure(tracked));
 			}
 		}
 
@@ -1005,7 +1074,7 @@ class MemTrackable
 			MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
 			if (accumulator)
 			{
-				accumulator->mChildSize -= MemFootprint<TRACKED>::measure(tracked);
+				accumulator->mChildSize.sample(accumulator->mChildSize.getLastValue() - (F64)MemFootprint<TRACKED>::measure(tracked));
 			}
 		}
 	};
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index 61ba21a3652..d32504b0142 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -213,7 +213,7 @@ LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumul
 				/ (F64)LLTrace::TimeBlock::countsPerSecond();
 }
 
-LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumulator::SelfTimeAspect>& stat)
+LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat)
 {
 	const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
 	update();
@@ -221,7 +221,7 @@ LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumul
 }
 
 
-U32 Recording::getSum(const TraceType<TimeBlockAccumulator::CallCountAspect>& stat)
+U32 Recording::getSum(const TraceType<TimeBlockAccumulator::CallCountFacet>& stat)
 {
 	update();
 	return mBuffers->mStackTimers[stat.getIndex()].mCalls;
@@ -236,7 +236,7 @@ LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccu
 				/ ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds);
 }
 
-LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccumulator::SelfTimeAspect>& stat)
+LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat)
 {
 	const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
 
@@ -245,22 +245,82 @@ LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccu
 			/ ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds);
 }
 
-F32 Recording::getPerSec(const TraceType<TimeBlockAccumulator::CallCountAspect>& stat)
+F32 Recording::getPerSec(const TraceType<TimeBlockAccumulator::CallCountFacet>& stat)
 {
 	update();
 	return (F32)mBuffers->mStackTimers[stat.getIndex()].mCalls / mElapsedSeconds;
 }
 
-LLUnit<LLUnits::Bytes, U32> Recording::getSum(const TraceType<MemStatAccumulator>& stat)
+LLUnit<LLUnits::Bytes, F64> Recording::getMin(const TraceType<MemStatAccumulator>& stat)
+{
+	update();
+	return mBuffers->mMemStats[stat.getIndex()].mSize.getMin();
+}
+
+LLUnit<LLUnits::Bytes, F64> Recording::getMean(const TraceType<MemStatAccumulator>& stat)
+{
+	update();
+	return mBuffers->mMemStats[stat.getIndex()].mSize.getMean();
+}
+
+LLUnit<LLUnits::Bytes, F64> Recording::getMax(const TraceType<MemStatAccumulator>& stat)
+{
+	update();
+	return mBuffers->mMemStats[stat.getIndex()].mSize.getMax();
+}
+
+LLUnit<LLUnits::Bytes, F64> Recording::getStandardDeviation(const TraceType<MemStatAccumulator>& stat)
+{
+	update();
+	return mBuffers->mMemStats[stat.getIndex()].mSize.getStandardDeviation();
+}
+
+LLUnit<LLUnits::Bytes, F64> Recording::getLastValue(const TraceType<MemStatAccumulator>& stat)
+{
+	update();
+	return mBuffers->mMemStats[stat.getIndex()].mSize.getLastValue();
+}
+
+LLUnit<LLUnits::Bytes, F64> Recording::getMin(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
+{
+	update();
+	return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMin();
+}
+
+LLUnit<LLUnits::Bytes, F64> Recording::getMean(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
+{
+	update();
+	return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMean();
+}
+
+LLUnit<LLUnits::Bytes, F64> Recording::getMax(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
+{
+	update();
+	return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMax();
+}
+
+LLUnit<LLUnits::Bytes, F64> Recording::getStandardDeviation(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
+{
+	update();
+	return mBuffers->mMemStats[stat.getIndex()].mChildSize.getStandardDeviation();
+}
+
+LLUnit<LLUnits::Bytes, F64> Recording::getLastValue(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
+{
+	update();
+	return mBuffers->mMemStats[stat.getIndex()].mChildSize.getLastValue();
+}
+
+U32 Recording::getSum(const TraceType<MemStatAccumulator::AllocationCountFacet>& stat)
 {
 	update();
 	return mBuffers->mMemStats[stat.getIndex()].mAllocatedCount;
 }
 
-LLUnit<LLUnits::Bytes, F32> Recording::getPerSec(const TraceType<MemStatAccumulator>& stat)
+U32 Recording::getSum(const TraceType<MemStatAccumulator::DeallocationCountFacet>& stat)
 {
 	update();
-	return (F32)mBuffers->mMemStats[stat.getIndex()].mAllocatedCount / mElapsedSeconds;
+	return mBuffers->mMemStats[stat.getIndex()].mAllocatedCount;
 }
 
 
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index b4452d67a09..4651bfcb61d 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -149,16 +149,28 @@ namespace LLTrace
 
 		// Timer accessors
 		LLUnit<LLUnits::Seconds, F64> getSum(const TraceType<TimeBlockAccumulator>& stat);
-		LLUnit<LLUnits::Seconds, F64> getSum(const TraceType<TimeBlockAccumulator::SelfTimeAspect>& stat);
-		U32 getSum(const TraceType<TimeBlockAccumulator::CallCountAspect>& stat);
+		LLUnit<LLUnits::Seconds, F64> getSum(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat);
+		U32 getSum(const TraceType<TimeBlockAccumulator::CallCountFacet>& stat);
 
 		LLUnit<LLUnits::Seconds, F64> getPerSec(const TraceType<TimeBlockAccumulator>& stat);
-		LLUnit<LLUnits::Seconds, F64> getPerSec(const TraceType<TimeBlockAccumulator::SelfTimeAspect>& stat);
-		F32 getPerSec(const TraceType<TimeBlockAccumulator::CallCountAspect>& stat);
+		LLUnit<LLUnits::Seconds, F64> getPerSec(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat);
+		F32 getPerSec(const TraceType<TimeBlockAccumulator::CallCountFacet>& stat);
 
 		// Memory accessors
-		LLUnit<LLUnits::Bytes, U32> getSum(const TraceType<MemStatAccumulator>& stat);
-		LLUnit<LLUnits::Bytes, F32> getPerSec(const TraceType<MemStatAccumulator>& stat);
+		LLUnit<LLUnits::Bytes, F64> getMin(const TraceType<MemStatAccumulator>& stat);
+		LLUnit<LLUnits::Bytes, F64> getMean(const TraceType<MemStatAccumulator>& stat);
+		LLUnit<LLUnits::Bytes, F64> getMax(const TraceType<MemStatAccumulator>& stat);
+		LLUnit<LLUnits::Bytes, F64> getStandardDeviation(const TraceType<MemStatAccumulator>& stat);
+		LLUnit<LLUnits::Bytes, F64> getLastValue(const TraceType<MemStatAccumulator>& stat);
+
+		LLUnit<LLUnits::Bytes, F64> getMin(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
+		LLUnit<LLUnits::Bytes, F64> getMean(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
+		LLUnit<LLUnits::Bytes, F64> getMax(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
+		LLUnit<LLUnits::Bytes, F64> getStandardDeviation(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
+		LLUnit<LLUnits::Bytes, F64> getLastValue(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
+
+		U32 getSum(const TraceType<MemStatAccumulator::AllocationCountFacet>& stat);
+		U32 getSum(const TraceType<MemStatAccumulator::DeallocationCountFacet>& stat);
 
 		// CountStatHandle accessors
 		F64 getSum(const TraceType<CountAccumulator>& stat);
@@ -186,18 +198,18 @@ namespace LLTrace
 			return (T)getMin(static_cast<const TraceType<SampleAccumulator>&> (stat));
 		}
 
-		F64 getMax(const TraceType<SampleAccumulator>& stat);
+		F64 getMean(const TraceType<SampleAccumulator>& stat);
 		template <typename T>
-		T getMax(const SampleStatHandle<T>& stat)
+		T getMean(SampleStatHandle<T>& stat)
 		{
-			return (T)getMax(static_cast<const TraceType<SampleAccumulator>&> (stat));
+			return (T)getMean(static_cast<const TraceType<SampleAccumulator>&> (stat));
 		}
 
-		F64 getMean(const TraceType<SampleAccumulator>& stat);
+		F64 getMax(const TraceType<SampleAccumulator>& stat);
 		template <typename T>
-		T getMean(SampleStatHandle<T>& stat)
+		T getMax(const SampleStatHandle<T>& stat)
 		{
-			return (T)getMean(static_cast<const TraceType<SampleAccumulator>&> (stat));
+			return (T)getMax(static_cast<const TraceType<SampleAccumulator>&> (stat));
 		}
 
 		F64 getStandardDeviation(const TraceType<SampleAccumulator>& stat);
diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h
index 77c19b5152b..a5406fb3f01 100644
--- a/indra/llcommon/llunit.h
+++ b/indra/llcommon/llunit.h
@@ -34,24 +34,10 @@
 namespace LLUnits
 {
 
-template<typename T>
-struct HighestPrecisionType
-{
-	typedef T type_t;
-};
-
-template<> struct HighestPrecisionType<F32> { typedef F64 type_t; };
-template<> struct HighestPrecisionType<S32> { typedef S64 type_t; };
-template<> struct HighestPrecisionType<U32> { typedef S64 type_t; };
-template<> struct HighestPrecisionType<S16> { typedef S64 type_t; };
-template<> struct HighestPrecisionType<U16> { typedef S64 type_t; };
-template<> struct HighestPrecisionType<S8> { typedef S64 type_t; };
-template<> struct HighestPrecisionType<U8> { typedef S64 type_t; };
-
 template<typename DERIVED_UNITS_TAG, typename BASE_UNITS_TAG, typename VALUE_TYPE>
 struct ConversionFactor
 {
-	static typename HighestPrecisionType<VALUE_TYPE>::type_t get()
+	static F64 get()
 	{
 		// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
 		llstatic_assert_template(DERIVED_UNITS_TAG, false,  "Cannot convert between types.");
@@ -61,7 +47,7 @@ struct ConversionFactor
 template<typename BASE_UNITS_TAG, typename VALUE_TYPE>
 struct ConversionFactor<BASE_UNITS_TAG, BASE_UNITS_TAG, VALUE_TYPE>
 {
-	static typename HighestPrecisionType<VALUE_TYPE>::type_t get() 
+	static F64 get() 
 	{ 
 		return 1; 
 	}
@@ -433,12 +419,6 @@ STORAGE_TYPE rawValue(LLUnit<UNIT_TYPE, STORAGE_TYPE> val) { return val.value();
 template<typename UNIT_TYPE, typename STORAGE_TYPE> 
 STORAGE_TYPE rawValue(LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> val) { return val.value(); }
 
-template<typename UNIT_TYPE, typename STORAGE_TYPE> 
-struct HighestPrecisionType<LLUnit<UNIT_TYPE, STORAGE_TYPE> >
-{
-	typedef typename HighestPrecisionType<STORAGE_TYPE>::type_t type_t;
-};
-
 #define LL_DECLARE_DERIVED_UNIT(conversion_factor, base_unit_name, unit_name, unit_label)		\
 struct unit_name                                                                                \
 {                                                                                               \
@@ -448,49 +428,54 @@ struct unit_name
 template<typename STORAGE_TYPE>                                                                 \
 struct ConversionFactor<unit_name, base_unit_name, STORAGE_TYPE>                                \
 {                                                                                               \
-	static typename HighestPrecisionType<STORAGE_TYPE>::type_t get()                            \
+	static F64 get()                                                                            \
 	{                                                                                           \
-		return typename HighestPrecisionType<STORAGE_TYPE>::type_t(conversion_factor);          \
+		return (F64)conversion_factor;                                                          \
 	}                                                                                           \
 };                                                                                              \
 	                                                                                            \
 template<typename STORAGE_TYPE>                                                                 \
 struct ConversionFactor<base_unit_name, unit_name, STORAGE_TYPE>						        \
 {                                                                                               \
-	static typename HighestPrecisionType<STORAGE_TYPE>::type_t get()                            \
+	static F64 get()                                                                            \
 	{                                                                                           \
-		return typename HighestPrecisionType<STORAGE_TYPE>::type_t(1.0 / (conversion_factor));  \
+		return (F64)(1.0 / (conversion_factor));                                                \
 	}                                                                                           \
 }
 
-struct Bytes { typedef Bytes base_unit_t; static const char* getUnitLabel() { return "B"; }};
-LL_DECLARE_DERIVED_UNIT(1024, Bytes, Kilobytes, "KiB");
-LL_DECLARE_DERIVED_UNIT(1024 * 1024, Bytes, Megabytes, "MiB");
-LL_DECLARE_DERIVED_UNIT(1024 * 1024 * 1024, Bytes, Gigabytes, "GiB");
+#define LL_DECLARE_BASE_UNIT(base_unit_name, unit_label) \
+struct base_unit_name { typedef base_unit_name base_unit_t; static const char* getUnitLabel() { return unit_label; }}
+
+LL_DECLARE_BASE_UNIT(Bytes, "B");
+LL_DECLARE_DERIVED_UNIT(1024, Bytes, Kibibytes, "KiB");
+LL_DECLARE_DERIVED_UNIT(1024 * 1024, Bytes, Mibibytes, "MiB");
+LL_DECLARE_DERIVED_UNIT(1024 * 1024 * 1024, Bytes, Gibibytes, "GiB");
 LL_DECLARE_DERIVED_UNIT(1.0 / 8.0, Bytes, Bits, "b");
-LL_DECLARE_DERIVED_UNIT(1024 / 8, Bytes, Kilobits, "Kib");
-LL_DECLARE_DERIVED_UNIT(1024 / 8, Bytes, Megabits, "Mib");
-LL_DECLARE_DERIVED_UNIT(1024 * 1024 * 1024 / 8, Bytes, Gigabits, "Gib");
+LL_DECLARE_DERIVED_UNIT(1024 / 8, Bytes, Kibibits, "Kib");
+LL_DECLARE_DERIVED_UNIT(1024 / 8, Bytes, Mibibits, "Mib");
+LL_DECLARE_DERIVED_UNIT(1024 * 1024 * 1024 / 8, Bytes, Gibibits, "Gib");
 
-struct Seconds { typedef Seconds base_unit_t; static const char* getUnitLabel() { return "s"; } };
+LL_DECLARE_BASE_UNIT(Seconds, "s");
 LL_DECLARE_DERIVED_UNIT(60, Seconds, Minutes, "min");
 LL_DECLARE_DERIVED_UNIT(60 * 60, Seconds, Hours, "h");
 LL_DECLARE_DERIVED_UNIT(1.0 / 1000.0, Seconds, Milliseconds, "ms");
 LL_DECLARE_DERIVED_UNIT(1.0 / 1000000.0, Seconds, Microseconds, "\x09\x3cs");
 LL_DECLARE_DERIVED_UNIT(1.0 / 1000000000.0, Seconds, Nanoseconds, "ns");
 
-struct Meters { typedef Meters base_unit_t; static const char* getUnitLabel() { return "m"; } };
+LL_DECLARE_BASE_UNIT(Meters, "m");
 LL_DECLARE_DERIVED_UNIT(1000, Meters, Kilometers, "km");
 LL_DECLARE_DERIVED_UNIT(1.0 / 100.0, Meters, Centimeters, "cm");
 LL_DECLARE_DERIVED_UNIT(1.0 / 1000.0, Meters, Millimeters, "mm");
 
-struct Hertz { typedef Hertz base_unit_t; static const char* getUnitLabel() { return "Hz"; } };
+LL_DECLARE_BASE_UNIT(Hertz, "Hz");
 LL_DECLARE_DERIVED_UNIT(1000, Hertz, Kilohertz, "KHz");
 LL_DECLARE_DERIVED_UNIT(1000 * 1000, Hertz, Megahertz, "MHz");
 LL_DECLARE_DERIVED_UNIT(1000 * 1000 * 1000, Hertz, Gigahertz, "GHz");
 
-struct Radians { typedef Radians base_unit_t; static const char* getUnitLabel() { return "rad"; } };
+LL_DECLARE_BASE_UNIT(Radians, "rad");
 LL_DECLARE_DERIVED_UNIT(DEG_TO_RAD, Radians, Degrees, "deg");
+
+
 } // namespace LLUnits
 
 #endif // LL_LLUNIT_H
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index e7e274ff035..80634b38872 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -159,7 +159,7 @@ void LLImageBase::sanityCheck()
 void LLImageBase::deleteData()
 {
 	FREE_MEM(sPrivatePoolp, mData) ;
-	memDisclaim(mDataSize);
+	memDisclaimAmount(mDataSize);
 	mData = NULL;
 	mDataSize = 0;
 }
@@ -203,7 +203,7 @@ U8* LLImageBase::allocateData(S32 size)
 			mBadBufferAllocation = true ;
 		}
 		mDataSize = size;
-		memClaim(mDataSize);
+		memClaimAmount(mDataSize);
 	}
 
 	return mData;
@@ -225,9 +225,9 @@ U8* LLImageBase::reallocateData(S32 size)
 		FREE_MEM(sPrivatePoolp, mData) ;
 	}
 	mData = new_datap;
-	memDisclaim(mDataSize);
+	memDisclaimAmount(mDataSize);
 	mDataSize = size;
-	memClaim(mDataSize);
+	memClaimAmount(mDataSize);
 	return mData;
 }
 
@@ -1589,9 +1589,9 @@ static void avg4_colors2(const U8* a, const U8* b, const U8* c, const U8* d, U8*
 void LLImageBase::setDataAndSize(U8 *data, S32 size)
 { 
 	ll_assert_aligned(data, 16);
-	memDisclaim(mDataSize);
+	memDisclaimAmount(mDataSize);
 	mData = data; mDataSize = size; 
-	memClaim(mDataSize);
+	memClaimAmount(mDataSize);
 }	
 
 //static
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp
index f7abb982e10..dccf8a2a17c 100644
--- a/indra/newview/llscenemonitor.cpp
+++ b/indra/newview/llscenemonitor.cpp
@@ -554,6 +554,12 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
 		std::ostringstream row;
 		row << it->getName();
 
+		const char* unit_label = it->getUnitLabel();
+		if(unit_label[0])
+		{
+			row << "(" << unit_label << ")";
+		}
+
 		S32 samples = 0;
 
 		for (S32 frame = 0; frame < frame_count; frame++)
@@ -579,6 +585,12 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
 		std::ostringstream row;
 		row << it->getName();
 
+		const char* unit_label = it->getUnitLabel();
+		if(unit_label[0])
+		{
+			row << "(" << unit_label << ")";
+		}
+
 		S32 samples = 0;
 
 		for (S32 frame = 0; frame < frame_count; frame++)
@@ -600,11 +612,11 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
 		it != end_it;
 		++it)
 	{
-		os << it->getName();
+		os << it->getName() << "(KiB)";
 
 		for (S32 frame = 0; frame < frame_count; frame++)
 		{
-			os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getSum(*it).value();
+			os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(*it).as<LLUnits::Kibibytes>().value();
 		}
 
 		os << std::endl;
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 7a6351c880f..0df7b46b523 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -507,13 +507,13 @@ class LLGLTexMemBar : public LLView
 
 void LLGLTexMemBar::draw()
 {
-	LLUnit<LLUnits::Megabytes, S32> bound_mem = LLViewerTexture::sBoundTextureMemory;
- 	LLUnit<LLUnits::Megabytes, S32> max_bound_mem = LLViewerTexture::sMaxBoundTextureMem;
-	LLUnit<LLUnits::Megabytes, S32> total_mem = LLViewerTexture::sTotalTextureMemory;
-	LLUnit<LLUnits::Megabytes, S32> max_total_mem = LLViewerTexture::sMaxTotalTextureMem;
+	LLUnit<LLUnits::Mibibytes, S32> bound_mem = LLViewerTexture::sBoundTextureMemory;
+ 	LLUnit<LLUnits::Mibibytes, S32> max_bound_mem = LLViewerTexture::sMaxBoundTextureMem;
+	LLUnit<LLUnits::Mibibytes, S32> total_mem = LLViewerTexture::sTotalTextureMemory;
+	LLUnit<LLUnits::Mibibytes, S32> max_total_mem = LLViewerTexture::sMaxTotalTextureMem;
 	F32 discard_bias = LLViewerTexture::sDesiredDiscardBias;
-	F32 cache_usage = (F32)LLTrace::Megabytes(LLAppViewer::getTextureCache()->getUsage()).value() ;
-	F32 cache_max_usage = (F32)LLTrace::Megabytes(LLAppViewer::getTextureCache()->getMaxUsage()).value() ;
+	F32 cache_usage = (F32)LLTrace::Mibibytes(LLAppViewer::getTextureCache()->getUsage()).value() ;
+	F32 cache_max_usage = (F32)LLTrace::Mibibytes(LLAppViewer::getTextureCache()->getMaxUsage()).value() ;
 	S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
 	S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);
 	LLUnit<LLUnits::Bytes, F32> total_texture_downloaded = gTotalTextureData;
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 06a53787e7c..d29d1ebe5fe 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -89,7 +89,7 @@ LLTrace::CountStatHandle<>	FPS("framesrendered"),
 							TEX_BAKES("texbakes"),
 							TEX_REBAKES("texrebakes"),
 							NUM_NEW_OBJECTS("numnewobjectsstat");
-LLTrace::CountStatHandle<LLTrace::Kilobits>	KBIT("kbitstat"),
+LLTrace::CountStatHandle<LLTrace::Kibibits>	KBIT("kbitstat"),
 											LAYERS_KBIT("layerskbitstat"),
 											OBJECT_KBIT("objectkbitstat"),
 											ASSET_KBIT("assetkbitstat"),
@@ -552,9 +552,9 @@ void send_stats()
 
 	LLSD &download = body["downloads"];
 
-	download["world_kbytes"] = LLTrace::Kilobytes(gTotalWorldData).value();
-	download["object_kbytes"] = LLTrace::Kilobytes(gTotalObjectData).value();
-	download["texture_kbytes"] = LLTrace::Kilobytes(gTotalTextureData).value();
+	download["world_kbytes"] = LLTrace::Kibibytes(gTotalWorldData).value();
+	download["object_kbytes"] = LLTrace::Kibibytes(gTotalObjectData).value();
+	download["texture_kbytes"] = LLTrace::Kibibytes(gTotalTextureData).value();
 	download["mesh_kbytes"] = LLMeshRepository::sBytesReceived/1024.0;
 
 	LLSD &in = body["stats"]["net"]["in"];
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index ca8c347afa4..7ad1e5d0534 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -94,7 +94,7 @@ extern LLTrace::CountStatHandle<>			FPS,
 											NUM_NEW_OBJECTS;
 
 
-extern LLTrace::CountStatHandle<LLTrace::Kilobits>	KBIT,
+extern LLTrace::CountStatHandle<LLTrace::Kibibits>	KBIT,
 											LAYERS_KBIT,
 											OBJECT_KBIT,
 											ASSET_KBIT,
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 12835002d34..a3cd2efd661 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -65,8 +65,8 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 // extern
-const LLUnit<LLUnits::Megabytes, S32> gMinVideoRam = 32;
-const LLUnit<LLUnits::Megabytes, S32> gMaxVideoRam = 512;
+const LLUnit<LLUnits::Mibibytes, S32> gMinVideoRam = 32;
+const LLUnit<LLUnits::Mibibytes, S32> gMaxVideoRam = 512;
 
 
 // statics
@@ -89,8 +89,8 @@ F32 LLViewerTexture::sDesiredDiscardBias = 0.f;
 F32 LLViewerTexture::sDesiredDiscardScale = 1.1f;
 LLUnit<LLUnits::Bytes, S32> LLViewerTexture::sBoundTextureMemory = 0;
 LLUnit<LLUnits::Bytes, S32> LLViewerTexture::sTotalTextureMemory = 0;
-LLUnit<LLUnits::Megabytes, S32> LLViewerTexture::sMaxBoundTextureMem = 0;
-LLUnit<LLUnits::Megabytes, S32> LLViewerTexture::sMaxTotalTextureMem = 0;
+LLUnit<LLUnits::Mibibytes, S32> LLViewerTexture::sMaxBoundTextureMem = 0;
+LLUnit<LLUnits::Mibibytes, S32> LLViewerTexture::sMaxTotalTextureMem = 0;
 LLUnit<LLUnits::Bytes, S32> LLViewerTexture::sMaxDesiredTextureMem = 0 ;
 S8  LLViewerTexture::sCameraMovingDiscardBias = 0 ;
 F32 LLViewerTexture::sCameraMovingBias = 0.0f ;
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index d69a0ffb722..ff1aef181b7 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -39,8 +39,8 @@
 #include <map>
 #include <list>
 
-extern const LLUnit<LLUnits::Megabytes, S32> gMinVideoRam;
-extern const LLUnit<LLUnits::Megabytes, S32> gMaxVideoRam;
+extern const LLUnit<LLUnits::Mibibytes, S32> gMinVideoRam;
+extern const LLUnit<LLUnits::Mibibytes, S32> gMaxVideoRam;
 
 class LLFace;
 class LLImageGL ;
@@ -329,8 +329,8 @@ class LLViewerTexture : public LLTexture
 	static F32 sDesiredDiscardScale;
 	static LLUnit<LLUnits::Bytes, S32> sBoundTextureMemory;
 	static LLUnit<LLUnits::Bytes, S32> sTotalTextureMemory;
-	static LLUnit<LLUnits::Megabytes, S32> sMaxBoundTextureMem;
-	static LLUnit<LLUnits::Megabytes, S32> sMaxTotalTextureMem;
+	static LLUnit<LLUnits::Mibibytes, S32> sMaxBoundTextureMem;
+	static LLUnit<LLUnits::Mibibytes, S32> sMaxTotalTextureMem;
 	static LLUnit<LLUnits::Bytes, S32> sMaxDesiredTextureMem ;
 	static S8  sCameraMovingDiscardBias;
 	static F32 sCameraMovingBias;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index ed856674694..9523037b36b 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -734,7 +734,7 @@ class LLDebugText
 			{
 				if(gTotalTextureBytesPerBoostLevel[i] > 0)
 				{
-					addText(xpos, ypos, llformat("Boost_Level %d:  %.3f MB", i, LLUnit<LLUnits::Megabytes, F32>(gTotalTextureBytesPerBoostLevel[i]).value()));
+					addText(xpos, ypos, llformat("Boost_Level %d:  %.3f MB", i, LLUnit<LLUnits::Mibibytes, F32>(gTotalTextureBytesPerBoostLevel[i]).value()));
 					ypos += y_inc;
 				}
 			}
-- 
GitLab