blob: 4d9a5241b731f73e709c22eecfc412870b87c426 [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 {
82 RawSenderTiming(int new_channel_index) : channel_index(new_channel_index) {}
83
84 void set_timing_report(timing::Sender *sender);
85 void ResetTimingReport();
86
87 const int channel_index;
88 timing::Sender *sender = nullptr;
89 internal::TimingStatistic size;
90};
91
92// Class to hold timing information for timers.
93struct TimerTiming {
94 void set_timing_report(timing::Timer *timer);
95 void ResetTimingReport();
96
97 internal::TimingStatistic wakeup_latency;
98 internal::TimingStatistic handler_time;
99 timing::Timer *timer = nullptr;
100};
101
102} // namespace internal
103} // namespace aos
104
105#endif // AOS_EVENTS_TIMING_STATISTICS_H_