xref: /openbmc/linux/tools/perf/util/stat.c (revision 45471cd98decae5fced8b38e46c223f54a924814)
1 #include <math.h>
2 #include "stat.h"
3 #include "evsel.h"
4 
5 void update_stats(struct stats *stats, u64 val)
6 {
7 	double delta;
8 
9 	stats->n++;
10 	delta = val - stats->mean;
11 	stats->mean += delta / stats->n;
12 	stats->M2 += delta*(val - stats->mean);
13 
14 	if (val > stats->max)
15 		stats->max = val;
16 
17 	if (val < stats->min)
18 		stats->min = val;
19 }
20 
21 double avg_stats(struct stats *stats)
22 {
23 	return stats->mean;
24 }
25 
26 /*
27  * http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
28  *
29  *       (\Sum n_i^2) - ((\Sum n_i)^2)/n
30  * s^2 = -------------------------------
31  *                  n - 1
32  *
33  * http://en.wikipedia.org/wiki/Stddev
34  *
35  * The std dev of the mean is related to the std dev by:
36  *
37  *             s
38  * s_mean = -------
39  *          sqrt(n)
40  *
41  */
42 double stddev_stats(struct stats *stats)
43 {
44 	double variance, variance_mean;
45 
46 	if (stats->n < 2)
47 		return 0.0;
48 
49 	variance = stats->M2 / (stats->n - 1);
50 	variance_mean = variance / stats->n;
51 
52 	return sqrt(variance_mean);
53 }
54 
55 double rel_stddev_stats(double stddev, double avg)
56 {
57 	double pct = 0.0;
58 
59 	if (avg)
60 		pct = 100.0 * stddev/avg;
61 
62 	return pct;
63 }
64 
65 bool __perf_evsel_stat__is(struct perf_evsel *evsel,
66 			   enum perf_stat_evsel_id id)
67 {
68 	struct perf_stat *ps = evsel->priv;
69 
70 	return ps->id == id;
71 }
72 
73 #define ID(id, name) [PERF_STAT_EVSEL_ID__##id] = #name
74 static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = {
75 	ID(NONE,		x),
76 	ID(CYCLES_IN_TX,	cpu/cycles-t/),
77 	ID(TRANSACTION_START,	cpu/tx-start/),
78 	ID(ELISION_START,	cpu/el-start/),
79 	ID(CYCLES_IN_TX_CP,	cpu/cycles-ct/),
80 };
81 #undef ID
82 
83 void perf_stat_evsel_id_init(struct perf_evsel *evsel)
84 {
85 	struct perf_stat *ps = evsel->priv;
86 	int i;
87 
88 	/* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */
89 
90 	for (i = 0; i < PERF_STAT_EVSEL_ID__MAX; i++) {
91 		if (!strcmp(perf_evsel__name(evsel), id_str[i])) {
92 			ps->id = i;
93 			break;
94 		}
95 	}
96 }
97 
98 struct perf_counts *perf_counts__new(int ncpus)
99 {
100 	int size = sizeof(struct perf_counts) +
101 		   ncpus * sizeof(struct perf_counts_values);
102 
103 	return zalloc(size);
104 }
105 
106 void perf_counts__delete(struct perf_counts *counts)
107 {
108 	free(counts);
109 }
110 
111 static void perf_counts__reset(struct perf_counts *counts, int ncpus)
112 {
113 	memset(counts, 0, (sizeof(*counts) +
114 	       (ncpus * sizeof(struct perf_counts_values))));
115 }
116 
117 void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus)
118 {
119 	perf_counts__reset(evsel->counts, ncpus);
120 }
121 
122 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus)
123 {
124 	evsel->counts = perf_counts__new(ncpus);
125 	return evsel->counts != NULL ? 0 : -ENOMEM;
126 }
127 
128 void perf_evsel__free_counts(struct perf_evsel *evsel)
129 {
130 	perf_counts__delete(evsel->counts);
131 	evsel->counts = NULL;
132 }
133