summaryrefslogtreecommitdiffstats
path: root/services/audioflinger/FastMixer.cpp
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2012-09-07 12:58:38 -0700
committerGlenn Kasten <gkasten@google.com>2012-09-07 12:58:38 -0700
commit1ab212cf5cfa5b88c801840e11e3191cd10f48e4 (patch)
tree247292feb5fe019488a87ff64926643fa84e766e /services/audioflinger/FastMixer.cpp
parentd06ab147394b0b49679c924a51d77c91dea04d82 (diff)
downloadframeworks_av-1ab212cf5cfa5b88c801840e11e3191cd10f48e4.zip
frameworks_av-1ab212cf5cfa5b88c801840e11e3191cd10f48e4.tar.gz
frameworks_av-1ab212cf5cfa5b88c801840e11e3191cd10f48e4.tar.bz2
Add outlier statistics for fast mixer cycle times
Change-Id: I31c964caeb8b5d9ae0a426224f030cdcb01114a0
Diffstat (limited to 'services/audioflinger/FastMixer.cpp')
-rw-r--r--services/audioflinger/FastMixer.cpp41
1 files changed, 40 insertions, 1 deletions
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index fbcc11a..cdc27a2 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -612,6 +612,20 @@ FastMixerDumpState::~FastMixerDumpState()
{
}
+// helper function called by qsort()
+static int compare_uint32_t(const void *pa, const void *pb)
+{
+ uint32_t a = *(const uint32_t *)pa;
+ uint32_t b = *(const uint32_t *)pb;
+ if (a < b) {
+ return -1;
+ } else if (a > b) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
void FastMixerDumpState::dump(int fd)
{
if (mCommand == FastMixerState::INITIAL) {
@@ -674,10 +688,18 @@ void FastMixerDumpState::dump(int fd)
CentralTendencyStatistics kHz, loadMHz;
uint32_t previousCpukHz = 0;
#endif
+ // Assuming a normal distribution for cycle times, three standard deviations on either side of
+ // the mean account for 99.73% of the population. So if we take each tail to be 1/1000 of the
+ // sample set, we get 99.8% combined, or close to three standard deviations.
+ static const uint32_t kTailDenominator = 1000;
+ uint32_t *tail = n >= kTailDenominator ? new uint32_t[n] : NULL;
// loop over all the samples
- for (; n > 0; --n) {
+ for (uint32_t j = 0; j < n; ++j) {
size_t i = oldestClosed++ & (kSamplingN - 1);
uint32_t wallNs = mMonotonicNs[i];
+ if (tail != NULL) {
+ tail[j] = wallNs;
+ }
wall.sample(wallNs);
uint32_t sampleLoadNs = mLoadNs[i];
loadNs.sample(sampleLoadNs);
@@ -711,6 +733,23 @@ void FastMixerDumpState::dump(int fd)
" mean=%.1f min=%.1f max=%.1f stddev=%.1f\n",
loadMHz.mean(), loadMHz.minimum(), loadMHz.maximum(), loadMHz.stddev());
#endif
+ if (tail != NULL) {
+ qsort(tail, n, sizeof(uint32_t), compare_uint32_t);
+ // assume same number of tail samples on each side, left and right
+ uint32_t count = n / kTailDenominator;
+ CentralTendencyStatistics left, right;
+ for (uint32_t i = 0; i < count; ++i) {
+ left.sample(tail[i]);
+ right.sample(tail[n - (i + 1)]);
+ }
+ fdprintf(fd, "Distribution of mix cycle times in ms for the tails (> ~3 stddev outliers):\n"
+ " left tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n"
+ " right tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
+ left.mean()*1e-6, left.minimum()*1e-6, left.maximum()*1e-6, left.stddev()*1e-6,
+ right.mean()*1e-6, right.minimum()*1e-6, right.maximum()*1e-6,
+ right.stddev()*1e-6);
+ delete[] tail;
+ }
#endif
// The active track mask and track states are updated non-atomically.
// So if we relied on isActive to decide whether to display,