blob: e9edff24009b027fe7468469ebe07b276efe8cbf [file] [log] [blame]
Austin Schuhe4106142019-12-01 18:19:53 -08001#ifndef AOS_EVENTS_TIMING_STATISTICS_H_
2#define AOS_EVENTS_TIMING_STATISTICS_H_
3
4#include <cmath>
5
6#include "aos/events/event_loop_generated.h"
7
8namespace aos {
9namespace internal {
10
11// Class to compute statistics for the timing report.
12class TimingStatistic {
13 public:
14 TimingStatistic() {}
15
16 // Sets the flatbuffer to mutate.
17 void set_statistic(timing::Statistic *statistic) { statistic_ = statistic; }
18
19 // Adds a sample to the statistic.
20 void Add(float sample) {
Brian Silvermanbf889922021-11-10 12:41:57 -080021 if (!statistic_) {
22 return;
23 }
24
Austin Schuhe4106142019-12-01 18:19:53 -080025 ++count_;
26 if (count_ == 1) {
27 statistic_->mutate_average(sample);
28 statistic_->mutate_min(sample);
29 statistic_->mutate_max(sample);
30 statistic_->mutate_standard_deviation(0.0);
31 } else {
32 // https://en.wikipedia.org/wiki/Standard_deviation#Rapid_calculation_methods
33 const float prior_average = statistic_->average();
34 const float average = prior_average + (sample - prior_average) / count_;
35 statistic_->mutate_average(average);
36 statistic_->mutate_max(std::max(statistic_->max(), sample));
37 statistic_->mutate_min(std::min(statistic_->min(), sample));
38
39 Q_ = Q_ + (sample - prior_average) * (sample - average);
40 statistic_->mutate_standard_deviation(std::sqrt(Q_ / (count_ - 1)));
41 }
42 }
43
44 // Clears any accumulated statistics.
45 void Reset() {
Brian Silvermanbf889922021-11-10 12:41:57 -080046 if (!statistic_) {
47 return;
48 }
49
Austin Schuhe4106142019-12-01 18:19:53 -080050 statistic_->mutate_average(std::numeric_limits<float>::quiet_NaN());
51 statistic_->mutate_min(std::numeric_limits<float>::quiet_NaN());
52 statistic_->mutate_max(std::numeric_limits<float>::quiet_NaN());
53
54 statistic_->mutate_standard_deviation(
55 std::numeric_limits<float>::quiet_NaN());
56 Q_ = 0;
57 count_ = 0;
58 }
59
60 private:
61 timing::Statistic *statistic_ = nullptr;
62 // Number of samples accumulated.
63 size_t count_ = 0;
64 // State Q from wikipedia.
65 float Q_ = 0.0;
66};
67
68// Class to hold timing information for a raw fetcher.
69struct RawFetcherTiming {
70 RawFetcherTiming(int new_channel_index) : channel_index(new_channel_index) {}
71
72 void set_timing_report(timing::Fetcher *fetcher);
73 void ResetTimingReport();
74
75 const int channel_index;
76 timing::Fetcher *fetcher = nullptr;
77 internal::TimingStatistic latency;
78};
79
80// Class to hold timing information for a raw sender.
81struct RawSenderTiming {
James Kuszmaul78514332022-04-06 15:08:34 -070082 static constexpr size_t kNumErrors =
83 static_cast<int>(timing::SendError::MAX) -
84 static_cast<int>(timing::SendError::MIN) + 1;
85
Austin Schuhe4106142019-12-01 18:19:53 -080086 RawSenderTiming(int new_channel_index) : channel_index(new_channel_index) {}
87
88 void set_timing_report(timing::Sender *sender);
89 void ResetTimingReport();
James Kuszmaul78514332022-04-06 15:08:34 -070090 void IncrementError(timing::SendError error);
91 // Sanity check that the enum values are such that we can just use the enum
92 // values themselves as array indices without anything weird happening.
93 static_assert(0 == static_cast<int>(timing::SendError::MIN),
94 "Expected error enum values to start at zero.");
95 static_assert(
96 sizeof(std::invoke_result<decltype(timing::EnumValuesSendError)>::type) /
97 sizeof(timing::SendError) ==
98 kNumErrors,
99 "Expected continguous enum values.");
Austin Schuhe4106142019-12-01 18:19:53 -0800100
101 const int channel_index;
102 timing::Sender *sender = nullptr;
103 internal::TimingStatistic size;
104};
105
106// Class to hold timing information for timers.
107struct TimerTiming {
108 void set_timing_report(timing::Timer *timer);
109 void ResetTimingReport();
110
111 internal::TimingStatistic wakeup_latency;
112 internal::TimingStatistic handler_time;
113 timing::Timer *timer = nullptr;
114};
115
116} // namespace internal
117} // namespace aos
118
119#endif // AOS_EVENTS_TIMING_STATISTICS_H_