blob: ad0534a95d7b33312b2c0d6b5b437b7132fbf4b2 [file] [log] [blame]
#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_