Add definitions and helpers for timing reports
Add helpers for computing statistics. This requires us to add the
timing report definition too. These will be used shortly for building
timing reports.
Change-Id: I944ab60d84fd05f99faaa0b9cd0f9c8dc99c4429
diff --git a/aos/events/timing_statistics.h b/aos/events/timing_statistics.h
new file mode 100644
index 0000000..ad0534a
--- /dev/null
+++ b/aos/events/timing_statistics.h
@@ -0,0 +1,97 @@
+#ifndef AOS_EVENTS_TIMING_STATISTICS_H_
+#define AOS_EVENTS_TIMING_STATISTICS_H_
+
+#include <cmath>
+
+#include "aos/events/event_loop_generated.h"
+
+namespace aos {
+namespace internal {
+
+// Class to compute statistics for the timing report.
+class TimingStatistic {
+ public:
+ TimingStatistic() {}
+
+ // Sets the flatbuffer to mutate.
+ void set_statistic(timing::Statistic *statistic) { statistic_ = statistic; }
+
+ // Adds a sample to the statistic.
+ void Add(float sample) {
+ ++count_;
+ if (count_ == 1) {
+ statistic_->mutate_average(sample);
+ statistic_->mutate_min(sample);
+ statistic_->mutate_max(sample);
+ statistic_->mutate_standard_deviation(0.0);
+ } else {
+ // https://en.wikipedia.org/wiki/Standard_deviation#Rapid_calculation_methods
+ const float prior_average = statistic_->average();
+ const float average = prior_average + (sample - prior_average) / count_;
+ statistic_->mutate_average(average);
+ statistic_->mutate_max(std::max(statistic_->max(), sample));
+ statistic_->mutate_min(std::min(statistic_->min(), sample));
+
+ Q_ = Q_ + (sample - prior_average) * (sample - average);
+ statistic_->mutate_standard_deviation(std::sqrt(Q_ / (count_ - 1)));
+ }
+ }
+
+ // Clears any accumulated statistics.
+ void Reset() {
+ statistic_->mutate_average(std::numeric_limits<float>::quiet_NaN());
+ statistic_->mutate_min(std::numeric_limits<float>::quiet_NaN());
+ statistic_->mutate_max(std::numeric_limits<float>::quiet_NaN());
+
+ statistic_->mutate_standard_deviation(
+ std::numeric_limits<float>::quiet_NaN());
+ Q_ = 0;
+ count_ = 0;
+ }
+
+ private:
+ timing::Statistic *statistic_ = nullptr;
+ // Number of samples accumulated.
+ size_t count_ = 0;
+ // State Q from wikipedia.
+ float Q_ = 0.0;
+};
+
+// Class to hold timing information for a raw fetcher.
+struct RawFetcherTiming {
+ RawFetcherTiming(int new_channel_index) : channel_index(new_channel_index) {}
+
+ void set_timing_report(timing::Fetcher *fetcher);
+ void ResetTimingReport();
+
+ const int channel_index;
+ timing::Fetcher *fetcher = nullptr;
+ internal::TimingStatistic latency;
+};
+
+// Class to hold timing information for a raw sender.
+struct RawSenderTiming {
+ RawSenderTiming(int new_channel_index) : channel_index(new_channel_index) {}
+
+ void set_timing_report(timing::Sender *sender);
+ void ResetTimingReport();
+
+ const int channel_index;
+ timing::Sender *sender = nullptr;
+ internal::TimingStatistic size;
+};
+
+// Class to hold timing information for timers.
+struct TimerTiming {
+ void set_timing_report(timing::Timer *timer);
+ void ResetTimingReport();
+
+ internal::TimingStatistic wakeup_latency;
+ internal::TimingStatistic handler_time;
+ timing::Timer *timer = nullptr;
+};
+
+} // namespace internal
+} // namespace aos
+
+#endif // AOS_EVENTS_TIMING_STATISTICS_H_