Skip to content

Commit

Permalink
perf stat: More advanced variance computation
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Peter Zijlstra authored and Ingo Molnar committed Sep 4, 2009
1 parent 63d40de commit 8a02631
Showing 1 changed file with 12 additions and 12 deletions.
24 changes: 12 additions & 12 deletions tools/perf/builtin-stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand All @@ -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);
}
Expand Down

0 comments on commit 8a02631

Please sign in to comment.