blob: ad0534a95d7b33312b2c0d6b5b437b7132fbf4b2 [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) {
21 ++count_;
22 if (count_ == 1) {
23 statistic_->mutate_average(sample);
24 statistic_->mutate_min(sample);
25 statistic_->mutate_max(sample);
26 statistic_->mutate_standard_deviation(0.0);
27 } else {
28 // https://en.wikipedia.org/wiki/Standard_deviation#Rapid_calculation_methods
29 const float prior_average = statistic_->average();
30 const float average = prior_average + (sample - prior_average) / count_;
31 statistic_->mutate_average(average);
32 statistic_->mutate_max(std::max(statistic_->max(), sample));
33 statistic_->mutate_min(std::min(statistic_->min(), sample));
34
35 Q_ = Q_ + (sample - prior_average) * (sample - average);
36 statistic_->mutate_standard_deviation(std::sqrt(Q_ / (count_ - 1)));
37 }
38 }
39
40 // Clears any accumulated statistics.
41 void Reset() {
42 statistic_->mutate_average(std::numeric_limits<float>::quiet_NaN());
43 statistic_->mutate_min(std::numeric_limits<float>::quiet_NaN());
44 statistic_->mutate_max(std::numeric_limits<float>::quiet_NaN());
45
46 statistic_->mutate_standard_deviation(
47 std::numeric_limits<float>::quiet_NaN());
48 Q_ = 0;
49 count_ = 0;
50 }
51
52 private:
53 timing::Statistic *statistic_ = nullptr;
54 // Number of samples accumulated.
55 size_t count_ = 0;
56 // State Q from wikipedia.
57 float Q_ = 0.0;
58};
59
60// Class to hold timing information for a raw fetcher.
61struct RawFetcherTiming {
62 RawFetcherTiming(int new_channel_index) : channel_index(new_channel_index) {}
63
64 void set_timing_report(timing::Fetcher *fetcher);
65 void ResetTimingReport();
66
67 const int channel_index;
68 timing::Fetcher *fetcher = nullptr;
69 internal::TimingStatistic latency;
70};
71
72// Class to hold timing information for a raw sender.
73struct RawSenderTiming {
74 RawSenderTiming(int new_channel_index) : channel_index(new_channel_index) {}
75
76 void set_timing_report(timing::Sender *sender);
77 void ResetTimingReport();
78
79 const int channel_index;
80 timing::Sender *sender = nullptr;
81 internal::TimingStatistic size;
82};
83
84// Class to hold timing information for timers.
85struct TimerTiming {
86 void set_timing_report(timing::Timer *timer);
87 void ResetTimingReport();
88
89 internal::TimingStatistic wakeup_latency;
90 internal::TimingStatistic handler_time;
91 timing::Timer *timer = nullptr;
92};
93
94} // namespace internal
95} // namespace aos
96
97#endif // AOS_EVENTS_TIMING_STATISTICS_H_