Organize PerformanceAnalysis members in structs
Stores related variables in structs instead of
directly in the class definition
Test: dumpsys media.log
Change-Id: I776e35e74ac69b428170b379a9bcf4d18b3fa041
diff --git a/media/libnbaio/PerformanceAnalysis.cpp b/media/libnbaio/PerformanceAnalysis.cpp
index 5746222..7f4548f 100644
--- a/media/libnbaio/PerformanceAnalysis.cpp
+++ b/media/libnbaio/PerformanceAnalysis.cpp
@@ -87,12 +87,12 @@
// if the current histogram has spanned its maximum time interval,
// insert a new empty histogram to the front of mHists
- if (deltaMs(mHists[0].first, mTimeStampSeries[0]) >= kMaxHistTimespanMs) {
+ if (deltaMs(mHists[0].first, mTimeStampSeries[0]) >= kMaxLength.HistTimespanMs) {
mHists.emplace_front(static_cast<uint64_t>(mTimeStampSeries[0]),
std::map<int, int>());
// When memory is full, delete oldest histogram
- if (mHists.size() >= kHistsCapacity) {
- mHists.resize(kHistsCapacity);
+ if (mHists.size() >= kMaxLength.Hists) {
+ mHists.resize(kMaxLength.Hists);
}
}
@@ -125,7 +125,7 @@
mTimeStampSeries.push_back(ts);
// if length of the time series has reached kShortHistSize samples,
// analyze the data and flush the timestamp series from memory
- if (mTimeStampSeries.size() >= kHistSize) {
+ if (mTimeStampSeries.size() >= kMaxLength.TimeStamps) {
processAndFlushTimeStampSeries();
}
}
@@ -152,36 +152,39 @@
// the mean and standard deviation are updated every time a peak is detected
// initialize first time. The mean from the previous sequence is stored
// for the next sequence. Here, they are initialized for the first time.
- if (mPeakDetectorMean < 0) {
- mPeakDetectorMean = static_cast<double>(start->first);
- mPeakDetectorSd = 0;
+ if (mOutlierDistribution.Mean < 0) {
+ mOutlierDistribution.Mean = static_cast<double>(start->first);
+ mOutlierDistribution.Sd = 0;
}
auto sqr = [](auto x){ return x * x; };
for (auto it = mOutlierData.begin(); it != mOutlierData.end(); ++it) {
// no surprise occurred:
// the new element is a small number of standard deviations from the mean
- if ((fabs(it->first - mPeakDetectorMean) < kStddevThreshold * mPeakDetectorSd) ||
+ if ((fabs(it->first - mOutlierDistribution.Mean) <
+ mOutlierDistribution.kMaxDeviation * mOutlierDistribution.Sd) ||
// or: right after peak has been detected, the delta is smaller than average
- (mPeakDetectorSd == 0 && fabs(it->first - mPeakDetectorMean) < kTypicalDiff)) {
+ (mOutlierDistribution.Sd == 0 &&
+ fabs(it->first - mOutlierDistribution.Mean) < kTypicalDiff)) {
// update the mean and sd:
// count number of elements (distance between start interator and current)
const int kN = std::distance(start, it) + 1;
// usual formulas for mean and sd
- mPeakDetectorMean = std::accumulate(start, it + 1, 0.0,
+ mOutlierDistribution.Mean = std::accumulate(start, it + 1, 0.0,
[](auto &a, auto &b){return a + b.first;}) / kN;
- mPeakDetectorSd = sqrt(std::accumulate(start, it + 1, 0.0,
- [=](auto &a, auto &b){ return a + sqr(b.first - mPeakDetectorMean);})) /
- ((kN > 1)? kN - 1 : kN); // kN - 1: mean is correlated with variance
+ mOutlierDistribution.Sd = sqrt(std::accumulate(start, it + 1, 0.0,
+ [=](auto &a, auto &b){
+ return a + sqr(b.first - mOutlierDistribution.Mean);})) /
+ ((kN > 1)? kN - 1 : kN); // kN - 1: mean is correlated with variance
}
// surprising value: store peak timestamp and reset mean, sd, and start iterator
else {
- mPeakTimestamps.emplace_back(it->second);
- // TODO: remove pop_front once a circular buffer is in place
- if (mPeakTimestamps.size() >= kPeakSeriesSize) {
- mPeakTimestamps.pop_front();
+ mPeakTimestamps.emplace_front(it->second);
+ // TODO: turn this into a circular buffer
+ if (mPeakTimestamps.size() >= kMaxLength.Peaks) {
+ mPeakTimestamps.resize(kMaxLength.Peaks);
}
- mPeakDetectorMean = static_cast<double>(it->first);
- mPeakDetectorSd = 0;
+ mOutlierDistribution.Mean = static_cast<double>(it->first);
+ mOutlierDistribution.Sd = 0;
start = it;
}
}
@@ -190,7 +193,8 @@
// Called by LogTsEntry. The input is a vector of timestamps.
// Finds outliers and writes to mOutlierdata.
-// Each value in mOutlierdata consists of: <outlier timestamp, time elapsed since previous outlier>.
+// Each value in mOutlierdata consists of: <outlier timestamp,
+// time elapsed since previous outlier>.
// e.g. timestamps (ms) 1, 4, 5, 16, 18, 28 will produce pairs (4, 5), (13, 18).
// This function is applied to the time series before it is converted into a histogram.
void PerformanceAnalysis::storeOutlierData(const std::vector<int64_t> ×tamps) {
@@ -198,24 +202,25 @@
return;
}
// first pass: need to initialize
- if (mElapsed == 0) {
- mPrevNs = timestamps[0];
+ if (mOutlierDistribution.Elapsed == 0) {
+ mOutlierDistribution.PrevNs = timestamps[0];
}
for (const auto &ts: timestamps) {
- const uint64_t diffMs = static_cast<uint64_t>(deltaMs(mPrevNs, ts));
+ const uint64_t diffMs = static_cast<uint64_t>(deltaMs(mOutlierDistribution.PrevNs, ts));
if (diffMs >= static_cast<uint64_t>(kOutlierMs)) {
- mOutlierData.emplace_back(mElapsed, static_cast<uint64_t>(mPrevNs));
+ mOutlierData.emplace_front(mOutlierDistribution.Elapsed,
+ static_cast<uint64_t>(mOutlierDistribution.PrevNs));
// Remove oldest value if the vector is full
// TODO: remove pop_front once circular buffer is in place
// FIXME: make sure kShortHistSize is large enough that that data will never be lost
// before being written to file or to a FIFO
- if (mOutlierData.size() >= kOutlierSeriesSize) {
- mOutlierData.pop_front();
+ if (mOutlierData.size() >= kMaxLength.Outliers) {
+ mOutlierData.resize(kMaxLength.Outliers);
}
- mElapsed = 0;
+ mOutlierDistribution.Elapsed = 0;
}
- mElapsed += diffMs;
- mPrevNs = ts;
+ mOutlierDistribution.Elapsed += diffMs;
+ mOutlierDistribution.PrevNs = ts;
}
}
@@ -279,7 +284,8 @@
const int value = 1 << row;
body->appendFormat("%.*s", leftPadding, spaces.c_str());
for (auto const &x : buckets) {
- body->appendFormat("%.*s%s", colWidth - 1, spaces.c_str(), x.second < value ? " " : "|");
+ body->appendFormat("%.*s%s", colWidth - 1,
+ spaces.c_str(), x.second < value ? " " : "|");
}
body->appendFormat("\n%s", " ");
}
diff --git a/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h b/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
index dc6a989..81f9c58 100644
--- a/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
+++ b/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
@@ -102,10 +102,9 @@
// when a vector reaches its maximum size, the data is processed and flushed
std::vector<timestamp_raw> mTimeStampSeries;
- static const int kMsPerSec = 1000;
-
// Parameters used when detecting outliers
// TODO: learn some of these from the data, delete unused ones
+ // TODO: put used variables in a struct
// FIXME: decide whether to make kPeriodMs static.
static const int kNumBuff = 3; // number of buffers considered in local history
int kPeriodMs; // current period length is ideally 4 ms
@@ -114,27 +113,29 @@
static constexpr double kRatio = 0.75; // estimate of CPU time as ratio of period length
int kPeriodMsCPU; // compute based on kPeriodLen and kRatio
- // Peak detection: number of standard deviations from mean considered a significant change
- static const int kStddevThreshold = 5;
-
// capacity allocated to data structures
// TODO: make these values longer when testing is finished
- static const int kHistsCapacity = 20; // number of short-term histograms stored in memory
- static const int kHistSize = 1000; // max number of samples stored in a histogram
- static const int kOutlierSeriesSize = 100; // number of values stored in outlier array
- static const int kPeakSeriesSize = 100; // number of values stored in peak array
- // maximum elapsed time between first and last timestamp of a long-term histogram
- static const int kMaxHistTimespanMs = 5 * kMsPerSec;
+ struct MaxLength {
+ size_t Hists; // number of histograms stored in memory
+ size_t TimeStamps; // histogram size, e.g. maximum length of timestamp series
+ size_t Outliers; // number of values stored in outlier array
+ size_t Peaks; // number of values stored in peak array
+ // maximum elapsed time between first and last timestamp of a long-term histogram
+ int HistTimespanMs;
+ };
+ static constexpr MaxLength kMaxLength = {.Hists = 20, .TimeStamps = 1000,
+ .Outliers = 100, .Peaks = 100, .HistTimespanMs = 5 * kMsPerSec };
// these variables are stored in-class to ensure continuity while analyzing the timestamp
// series one short sequence at a time: the variables are not re-initialized every time.
- // FIXME: create inner class for these variables and decide which other ones to add to it
- double mPeakDetectorMean = -1;
- double mPeakDetectorSd = -1;
- // variables for storeOutlierData
- uint64_t mElapsed = 0;
- int64_t mPrevNs = -1;
-
+ struct OutlierDistribution {
+ double Mean = -1;
+ double Sd = -1;
+ uint64_t Elapsed = 0;
+ int64_t PrevNs = -1;
+ // number of standard deviations from mean considered a significant change
+ const int kMaxDeviation = 5;
+ } mOutlierDistribution;
};
void dump(int fd, int indent, PerformanceAnalysisMap &threadPerformanceAnalysis);
diff --git a/media/libnbaio/include/media/nbaio/ReportPerformance.h b/media/libnbaio/include/media/nbaio/ReportPerformance.h
index bfab470..ed97a23 100644
--- a/media/libnbaio/include/media/nbaio/ReportPerformance.h
+++ b/media/libnbaio/include/media/nbaio/ReportPerformance.h
@@ -29,6 +29,8 @@
namespace ReportPerformance {
+const int kMsPerSec = 1000;
+
// stores a histogram: key: observed buffer period. value: count
// TODO: unsigned, unsigned
using Histogram = std::map<int, int>;