stat.c 2.7 KB
Newer Older
1 2
#include <math.h>
#include "stat.h"
3
#include "evsel.h"
4 5 6 7 8 9 10 11 12

void update_stats(struct stats *stats, u64 val)
{
	double delta;

	stats->n++;
	delta = val - stats->mean;
	stats->mean += delta / stats->n;
	stats->M2 += delta*(val - stats->mean);
D
David Ahern 已提交
13 14 15 16 17 18

	if (val > stats->max)
		stats->max = val;

	if (val < stats->min)
		stats->min = val;
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
}

double avg_stats(struct stats *stats)
{
	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
 *
 * http://en.wikipedia.org/wiki/Stddev
 *
 * The std dev of the mean is related to the std dev by:
 *
 *             s
 * s_mean = -------
 *          sqrt(n)
 *
 */
double stddev_stats(struct stats *stats)
{
	double variance, variance_mean;

46
	if (stats->n < 2)
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
		return 0.0;

	variance = stats->M2 / (stats->n - 1);
	variance_mean = variance / stats->n;

	return sqrt(variance_mean);
}

double rel_stddev_stats(double stddev, double avg)
{
	double pct = 0.0;

	if (avg)
		pct = 100.0 * stddev/avg;

	return pct;
}
64 65 66 67 68 69 70 71 72 73 74

bool __perf_evsel_stat__is(struct perf_evsel *evsel,
			   enum perf_stat_evsel_id id)
{
	struct perf_stat *ps = evsel->priv;

	return ps->id == id;
}

#define ID(id, name) [PERF_STAT_EVSEL_ID__##id] = #name
static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = {
75 76 77 78 79
	ID(NONE,		x),
	ID(CYCLES_IN_TX,	cpu/cycles-t/),
	ID(TRANSACTION_START,	cpu/tx-start/),
	ID(ELISION_START,	cpu/el-start/),
	ID(CYCLES_IN_TX_CP,	cpu/cycles-ct/),
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
};
#undef ID

void perf_stat_evsel_id_init(struct perf_evsel *evsel)
{
	struct perf_stat *ps = evsel->priv;
	int i;

	/* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */

	for (i = 0; i < PERF_STAT_EVSEL_ID__MAX; i++) {
		if (!strcmp(perf_evsel__name(evsel), id_str[i])) {
			ps->id = i;
			break;
		}
	}
}
97

98
struct perf_counts *perf_counts__new(int ncpus, int nthreads)
99
{
100
	struct perf_counts *counts = zalloc(sizeof(*counts));
101

102
	if (counts) {
103
		struct xyarray *values;
104

105 106
		values = xyarray__new(ncpus, nthreads, sizeof(struct perf_counts_values));
		if (!values) {
107 108 109 110
			free(counts);
			return NULL;
		}

111
		counts->values = values;
112 113 114
	}

	return counts;
115 116 117 118
}

void perf_counts__delete(struct perf_counts *counts)
{
119
	if (counts) {
120
		xyarray__delete(counts->values);
121 122
		free(counts);
	}
123 124
}

125
static void perf_counts__reset(struct perf_counts *counts)
126
{
127
	xyarray__reset(counts->values);
128 129
}

130
void perf_evsel__reset_counts(struct perf_evsel *evsel)
131
{
132
	perf_counts__reset(evsel->counts);
133 134
}

135
int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads)
136
{
137
	evsel->counts = perf_counts__new(ncpus, nthreads);
138 139 140 141 142
	return evsel->counts != NULL ? 0 : -ENOMEM;
}

void perf_evsel__free_counts(struct perf_evsel *evsel)
{
143 144
	perf_counts__delete(evsel->counts);
	evsel->counts = NULL;
145
}