diff options
| author | Stefan Boberg <[email protected]> | 2021-09-30 14:44:32 +0200 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2021-09-30 14:44:32 +0200 |
| commit | dda5004708497e54bca99d72cf707ba63b6d7fb6 (patch) | |
| tree | 2fd5a08f23b005a7831899ea718cf6d4e95267cd | |
| parent | Merge branch 'main' of https://github.com/EpicGames/zen (diff) | |
| download | zen-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.h | 40 | ||||
| -rw-r--r-- | zencore/stats.cpp | 72 | ||||
| -rw-r--r-- | zencore/timer.cpp | 9 |
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() { |