aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2021-09-30 14:44:32 +0200
committerStefan Boberg <[email protected]>2021-09-30 14:44:32 +0200
commitdda5004708497e54bca99d72cf707ba63b6d7fb6 (patch)
tree2fd5a08f23b005a7831899ea718cf6d4e95267cd
parentMerge branch 'main' of https://github.com/EpicGames/zen (diff)
downloadzen-dda5004708497e54bca99d72cf707ba63b6d7fb6.tar.xz
zen-dda5004708497e54bca99d72cf707ba63b6d7fb6.zip
metrics: added OperationTiming which is a useful combination of a Meter and a Histogram, intended to track frequency and duration of certain operations
-rw-r--r--zencore/include/zencore/stats.h40
-rw-r--r--zencore/stats.cpp72
-rw-r--r--zencore/timer.cpp9
3 files changed, 120 insertions, 1 deletions
diff --git a/zencore/include/zencore/stats.h b/zencore/include/zencore/stats.h
index f61184ced..dfa8dac34 100644
--- a/zencore/include/zencore/stats.h
+++ b/zencore/include/zencore/stats.h
@@ -180,6 +180,46 @@ private:
std::atomic<int64_t> m_Count{0};
};
+/** Track timing and frequency of some operation
+
+ Example usage would be to track frequency and duration of network
+ requests, or function calls.
+
+ */
+class OperationTiming
+{
+public:
+ OperationTiming(int32_t SampleCount = 514);
+ ~OperationTiming();
+
+ void Update(int64_t Duration);
+ int64_t Max() const;
+ int64_t Min() const;
+ double Mean() const;
+ uint64_t Count() const;
+ SampleSnapshot Snapshot() const { return m_Histogram.Snapshot(); }
+
+ double Rate1() { return m_Meter.Rate1(); }
+ double Rate5() { return m_Meter.Rate5(); }
+ double Rate15() { return m_Meter.Rate15(); }
+ double MeanRate() const { return m_Meter.MeanRate(); }
+
+ struct Scope
+ {
+ Scope(OperationTiming& Outer);
+ ~Scope();
+
+ private:
+ OperationTiming& m_Outer;
+ uint64_t m_StartTick;
+ };
+
+private:
+ Meter m_Meter;
+ Histogram m_Histogram;
+};
+
+void EmitSnapshot(std::string_view Tag, OperationTiming& Stat, CbObjectWriter& Cbo);
void EmitSnapshot(std::string_view Tag, const Histogram& Stat, CbObjectWriter& Cbo);
void EmitSnapshot(std::string_view Tag, Meter& Stat, CbObjectWriter& Cbo);
diff --git a/zencore/stats.cpp b/zencore/stats.cpp
index 53086f3ec..34dc2828f 100644
--- a/zencore/stats.cpp
+++ b/zencore/stats.cpp
@@ -353,6 +353,78 @@ SampleSnapshot::GetValues() const
//////////////////////////////////////////////////////////////////////////
+OperationTiming::OperationTiming(int32_t SampleCount) : m_Histogram{SampleCount}
+{
+}
+
+OperationTiming::~OperationTiming()
+{
+}
+
+void
+OperationTiming::Update(int64_t Duration)
+{
+ m_Meter.Mark(1);
+ m_Histogram.Update(Duration);
+}
+
+int64_t
+OperationTiming::Max() const
+{
+ return m_Histogram.Max();
+}
+
+int64_t
+OperationTiming::Min() const
+{
+ return m_Histogram.Min();
+}
+
+double
+OperationTiming::Mean() const
+{
+ return m_Histogram.Mean();
+}
+
+uint64_t
+OperationTiming::Count() const
+{
+ return m_Meter.Count();
+}
+
+OperationTiming::Scope::Scope(OperationTiming& Outer) : m_Outer(Outer), m_StartTick(GetHifreqTimerValue())
+{
+}
+
+OperationTiming::Scope::~Scope()
+{
+ m_Outer.Update(GetHifreqTimerValue() - m_StartTick);
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+void
+EmitSnapshot(std::string_view Tag, OperationTiming& Stat, CbObjectWriter& Cbo)
+{
+ Cbo.BeginObject(Tag);
+
+ SampleSnapshot Snap = Stat.Snapshot();
+
+ Cbo << "count" << Stat.Count();
+
+ Cbo << "rate_mean" << Stat.MeanRate();
+ Cbo << "rate_1" << Stat.Rate1() << "rate_5" << Stat.Rate5() << "rate_15" << Stat.Rate15();
+
+ const double ToSeconds = GetHifreqTimerToSeconds();
+
+ Cbo << "t_avg" << Stat.Mean() * ToSeconds;
+ Cbo << "t_min" << Stat.Min() * ToSeconds << "t_max" << Stat.Max() * ToSeconds;
+ Cbo << "t_p75" << Snap.Get75Percentile() * ToSeconds << "t_p95" << Snap.Get95Percentile() * ToSeconds << "t_p99"
+ << Snap.Get99Percentile() * ToSeconds << "t_p999" << Snap.Get999Percentile() * ToSeconds;
+
+ Cbo.EndObject();
+}
+
void
EmitSnapshot(std::string_view Tag, const Histogram& Stat, CbObjectWriter& Cbo)
{
diff --git a/zencore/timer.cpp b/zencore/timer.cpp
index b2c6cb6a2..5d30d9b29 100644
--- a/zencore/timer.cpp
+++ b/zencore/timer.cpp
@@ -42,7 +42,8 @@ InternalGetHifreqTimerFrequency()
#endif
}
-static uint64_t QpcFreq = InternalGetHifreqTimerFrequency();
+uint64_t QpcFreq = InternalGetHifreqTimerFrequency();
+static const double QpcFactor = 1.0 / InternalGetHifreqTimerFrequency();
uint64_t
GetHifreqTimerFrequency()
@@ -50,6 +51,12 @@ GetHifreqTimerFrequency()
return QpcFreq;
}
+double
+GetHifreqTimerToSeconds()
+{
+ return QpcFactor;
+}
+
uint64_t
GetHifreqTimerFrequencySafe()
{