xref: /openbmc/linux/tools/perf/util/stat.c (revision a9a3a4d9)
10007eceaSXiao Guangrong #include <math.h>
20007eceaSXiao Guangrong #include "stat.h"
3e2f56da1SJiri Olsa #include "evsel.h"
40007eceaSXiao Guangrong 
50007eceaSXiao Guangrong void update_stats(struct stats *stats, u64 val)
60007eceaSXiao Guangrong {
70007eceaSXiao Guangrong 	double delta;
80007eceaSXiao Guangrong 
90007eceaSXiao Guangrong 	stats->n++;
100007eceaSXiao Guangrong 	delta = val - stats->mean;
110007eceaSXiao Guangrong 	stats->mean += delta / stats->n;
120007eceaSXiao Guangrong 	stats->M2 += delta*(val - stats->mean);
13ffe4f3c0SDavid Ahern 
14ffe4f3c0SDavid Ahern 	if (val > stats->max)
15ffe4f3c0SDavid Ahern 		stats->max = val;
16ffe4f3c0SDavid Ahern 
17ffe4f3c0SDavid Ahern 	if (val < stats->min)
18ffe4f3c0SDavid Ahern 		stats->min = val;
190007eceaSXiao Guangrong }
200007eceaSXiao Guangrong 
210007eceaSXiao Guangrong double avg_stats(struct stats *stats)
220007eceaSXiao Guangrong {
230007eceaSXiao Guangrong 	return stats->mean;
240007eceaSXiao Guangrong }
250007eceaSXiao Guangrong 
260007eceaSXiao Guangrong /*
270007eceaSXiao Guangrong  * http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
280007eceaSXiao Guangrong  *
290007eceaSXiao Guangrong  *       (\Sum n_i^2) - ((\Sum n_i)^2)/n
300007eceaSXiao Guangrong  * s^2 = -------------------------------
310007eceaSXiao Guangrong  *                  n - 1
320007eceaSXiao Guangrong  *
330007eceaSXiao Guangrong  * http://en.wikipedia.org/wiki/Stddev
340007eceaSXiao Guangrong  *
350007eceaSXiao Guangrong  * The std dev of the mean is related to the std dev by:
360007eceaSXiao Guangrong  *
370007eceaSXiao Guangrong  *             s
380007eceaSXiao Guangrong  * s_mean = -------
390007eceaSXiao Guangrong  *          sqrt(n)
400007eceaSXiao Guangrong  *
410007eceaSXiao Guangrong  */
420007eceaSXiao Guangrong double stddev_stats(struct stats *stats)
430007eceaSXiao Guangrong {
440007eceaSXiao Guangrong 	double variance, variance_mean;
450007eceaSXiao Guangrong 
4645528f7cSDavid Ahern 	if (stats->n < 2)
470007eceaSXiao Guangrong 		return 0.0;
480007eceaSXiao Guangrong 
490007eceaSXiao Guangrong 	variance = stats->M2 / (stats->n - 1);
500007eceaSXiao Guangrong 	variance_mean = variance / stats->n;
510007eceaSXiao Guangrong 
520007eceaSXiao Guangrong 	return sqrt(variance_mean);
530007eceaSXiao Guangrong }
540007eceaSXiao Guangrong 
550007eceaSXiao Guangrong double rel_stddev_stats(double stddev, double avg)
560007eceaSXiao Guangrong {
570007eceaSXiao Guangrong 	double pct = 0.0;
580007eceaSXiao Guangrong 
590007eceaSXiao Guangrong 	if (avg)
600007eceaSXiao Guangrong 		pct = 100.0 * stddev/avg;
610007eceaSXiao Guangrong 
620007eceaSXiao Guangrong 	return pct;
630007eceaSXiao Guangrong }
64e2f56da1SJiri Olsa 
65e2f56da1SJiri Olsa bool __perf_evsel_stat__is(struct perf_evsel *evsel,
66e2f56da1SJiri Olsa 			   enum perf_stat_evsel_id id)
67e2f56da1SJiri Olsa {
68e2f56da1SJiri Olsa 	struct perf_stat *ps = evsel->priv;
69e2f56da1SJiri Olsa 
70e2f56da1SJiri Olsa 	return ps->id == id;
71e2f56da1SJiri Olsa }
72e2f56da1SJiri Olsa 
73e2f56da1SJiri Olsa #define ID(id, name) [PERF_STAT_EVSEL_ID__##id] = #name
74e2f56da1SJiri Olsa static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = {
75e2f56da1SJiri Olsa 	ID(NONE,		x),
764c358d5cSJiri Olsa 	ID(CYCLES_IN_TX,	cpu/cycles-t/),
774c358d5cSJiri Olsa 	ID(TRANSACTION_START,	cpu/tx-start/),
784c358d5cSJiri Olsa 	ID(ELISION_START,	cpu/el-start/),
794c358d5cSJiri Olsa 	ID(CYCLES_IN_TX_CP,	cpu/cycles-ct/),
80e2f56da1SJiri Olsa };
81e2f56da1SJiri Olsa #undef ID
82e2f56da1SJiri Olsa 
83e2f56da1SJiri Olsa void perf_stat_evsel_id_init(struct perf_evsel *evsel)
84e2f56da1SJiri Olsa {
85e2f56da1SJiri Olsa 	struct perf_stat *ps = evsel->priv;
86e2f56da1SJiri Olsa 	int i;
87e2f56da1SJiri Olsa 
88e2f56da1SJiri Olsa 	/* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */
89e2f56da1SJiri Olsa 
90e2f56da1SJiri Olsa 	for (i = 0; i < PERF_STAT_EVSEL_ID__MAX; i++) {
91e2f56da1SJiri Olsa 		if (!strcmp(perf_evsel__name(evsel), id_str[i])) {
92e2f56da1SJiri Olsa 			ps->id = i;
93e2f56da1SJiri Olsa 			break;
94e2f56da1SJiri Olsa 		}
95e2f56da1SJiri Olsa 	}
96e2f56da1SJiri Olsa }
97a9a3a4d9SJiri Olsa 
98a9a3a4d9SJiri Olsa void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus)
99a9a3a4d9SJiri Olsa {
100a9a3a4d9SJiri Olsa 	memset(evsel->counts, 0, (sizeof(*evsel->counts) +
101a9a3a4d9SJiri Olsa 				 (ncpus * sizeof(struct perf_counts_values))));
102a9a3a4d9SJiri Olsa }
103a9a3a4d9SJiri Olsa 
104a9a3a4d9SJiri Olsa int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus)
105a9a3a4d9SJiri Olsa {
106a9a3a4d9SJiri Olsa 	evsel->counts = zalloc((sizeof(*evsel->counts) +
107a9a3a4d9SJiri Olsa 				(ncpus * sizeof(struct perf_counts_values))));
108a9a3a4d9SJiri Olsa 	return evsel->counts != NULL ? 0 : -ENOMEM;
109a9a3a4d9SJiri Olsa }
110a9a3a4d9SJiri Olsa 
111a9a3a4d9SJiri Olsa void perf_evsel__free_counts(struct perf_evsel *evsel)
112a9a3a4d9SJiri Olsa {
113a9a3a4d9SJiri Olsa 	zfree(&evsel->counts);
114a9a3a4d9SJiri Olsa }
115