diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2009-09-04 17:26:26 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-09-04 17:38:15 +0200 |
commit | 8a02631a470d6f2ccec7bcf79c1058b0d4240bce (patch) | |
tree | e9dc528dff1db2d7165f315f9c05877265561444 /tools/perf/builtin-stat.c | |
parent | 63d40deb2e7c64ed55943d49f078e09fc4b64b54 (diff) | |
download | lwn-8a02631a470d6f2ccec7bcf79c1058b0d4240bce.tar.gz lwn-8a02631a470d6f2ccec7bcf79c1058b0d4240bce.zip |
perf stat: More advanced variance computation
Use the more advanced single pass variance algorithm outlined
on the wikipedia page. This is numerically more stable for
larger sample sets.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-stat.c')
-rw-r--r-- | tools/perf/builtin-stat.c | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index e9424fa72420..32b5c003f7fc 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -79,29 +79,30 @@ static int event_scaled[MAX_COUNTERS]; struct stats { - double sum; - double sum_sq; + double n, mean, M2; }; static void update_stats(struct stats *stats, u64 val) { - double sq = val; + double delta; - stats->sum += val; - stats->sum_sq += sq * sq; + stats->n++; + delta = val - stats->mean; + stats->mean += delta / stats->n; + stats->M2 += delta*(val - stats->mean); } static double avg_stats(struct stats *stats) { - return stats->sum / run_count; + return stats->mean; } /* * http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance * - * (\Sum n_i^2) - ((\Sum n_i)^2)/n - * s^2 ------------------------------- - * n - 1 + * (\Sum n_i^2) - ((\Sum n_i)^2)/n + * s^2 = ------------------------------- + * n - 1 * * http://en.wikipedia.org/wiki/Stddev * @@ -114,9 +115,8 @@ static double avg_stats(struct stats *stats) */ static double stddev_stats(struct stats *stats) { - double avg = stats->sum / run_count; - double variance = (stats->sum_sq - stats->sum*avg)/(run_count - 1); - double variance_mean = variance / run_count; + double variance = stats->M2 / (stats->n - 1); + double variance_mean = variance / stats->n; return sqrt(variance_mean); } |