blob: b8c329f41f13f7a4f5f423942fe5a62e46ef8d60 [file] [log] [blame]
Xiao Guangrong0007ece2012-09-17 16:31:14 +08001#include <math.h>
Xiao Guangrong0007ece2012-09-17 16:31:14 +08002#include "stat.h"
Jiri Olsae2f56da2015-06-04 15:50:55 +02003#include "evsel.h"
Xiao Guangrong0007ece2012-09-17 16:31:14 +08004
5void 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);
David Ahernffe4f3c2013-08-02 14:05:40 -060013
14 if (val > stats->max)
15 stats->max = val;
16
17 if (val < stats->min)
18 stats->min = val;
Xiao Guangrong0007ece2012-09-17 16:31:14 +080019}
20
21double 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 */
42double stddev_stats(struct stats *stats)
43{
44 double variance, variance_mean;
45
David Ahern45528f72013-05-25 18:24:48 -060046 if (stats->n < 2)
Xiao Guangrong0007ece2012-09-17 16:31:14 +080047 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
55double 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}
Jiri Olsae2f56da2015-06-04 15:50:55 +020064
65bool __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
74static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = {
Jiri Olsa4c358d52015-06-03 16:25:52 +020075 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/),
Jiri Olsae2f56da2015-06-04 15:50:55 +020080};
81#undef ID
82
83void 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}
Jiri Olsaa9a3a4d2015-06-14 10:19:26 +020097
Jiri Olsaa6fa0032015-06-26 11:29:11 +020098struct perf_counts *perf_counts__new(int ncpus, int nthreads)
Jiri Olsa9df38e82015-06-14 10:19:27 +020099{
Jiri Olsaa8e02322015-06-26 11:29:10 +0200100 struct perf_counts *counts = zalloc(sizeof(*counts));
Jiri Olsa9df38e82015-06-14 10:19:27 +0200101
Jiri Olsaa8e02322015-06-26 11:29:10 +0200102 if (counts) {
Jiri Olsa57b28912015-06-26 11:29:12 +0200103 struct xyarray *values;
Jiri Olsaa8e02322015-06-26 11:29:10 +0200104
Jiri Olsa57b28912015-06-26 11:29:12 +0200105 values = xyarray__new(ncpus, nthreads, sizeof(struct perf_counts_values));
106 if (!values) {
Jiri Olsaa8e02322015-06-26 11:29:10 +0200107 free(counts);
108 return NULL;
109 }
110
Jiri Olsa57b28912015-06-26 11:29:12 +0200111 counts->values = values;
Jiri Olsaa8e02322015-06-26 11:29:10 +0200112 }
113
114 return counts;
Jiri Olsa9df38e82015-06-14 10:19:27 +0200115}
116
117void perf_counts__delete(struct perf_counts *counts)
118{
Jiri Olsaa8e02322015-06-26 11:29:10 +0200119 if (counts) {
Jiri Olsa57b28912015-06-26 11:29:12 +0200120 xyarray__delete(counts->values);
Jiri Olsaa8e02322015-06-26 11:29:10 +0200121 free(counts);
122 }
Jiri Olsa9df38e82015-06-14 10:19:27 +0200123}
124
Jiri Olsaa8e02322015-06-26 11:29:10 +0200125static void perf_counts__reset(struct perf_counts *counts)
Jiri Olsa9df38e82015-06-14 10:19:27 +0200126{
Jiri Olsa57b28912015-06-26 11:29:12 +0200127 xyarray__reset(counts->values);
Jiri Olsa9df38e82015-06-14 10:19:27 +0200128}
129
Jiri Olsaa8e02322015-06-26 11:29:10 +0200130void perf_evsel__reset_counts(struct perf_evsel *evsel)
Jiri Olsaa9a3a4d2015-06-14 10:19:26 +0200131{
Jiri Olsaa8e02322015-06-26 11:29:10 +0200132 perf_counts__reset(evsel->counts);
Jiri Olsaa9a3a4d2015-06-14 10:19:26 +0200133}
134
Jiri Olsaa6fa0032015-06-26 11:29:11 +0200135int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads)
Jiri Olsaa9a3a4d2015-06-14 10:19:26 +0200136{
Jiri Olsaa6fa0032015-06-26 11:29:11 +0200137 evsel->counts = perf_counts__new(ncpus, nthreads);
Jiri Olsaa9a3a4d2015-06-14 10:19:26 +0200138 return evsel->counts != NULL ? 0 : -ENOMEM;
139}
140
141void perf_evsel__free_counts(struct perf_evsel *evsel)
142{
Jiri Olsa9df38e82015-06-14 10:19:27 +0200143 perf_counts__delete(evsel->counts);
144 evsel->counts = NULL;
Jiri Olsaa9a3a4d2015-06-14 10:19:26 +0200145}
Jiri Olsa9689edf2015-06-26 11:29:14 +0200146
147void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
148{
149 int i;
150 struct perf_stat *ps = evsel->priv;
151
152 for (i = 0; i < 3; i++)
153 init_stats(&ps->res_stats[i]);
154
155 perf_stat_evsel_id_init(evsel);
156}
157
158int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
159{
160 evsel->priv = zalloc(sizeof(struct perf_stat));
161 if (evsel->priv == NULL)
162 return -ENOMEM;
163 perf_evsel__reset_stat_priv(evsel);
164 return 0;
165}
166
167void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
168{
169 zfree(&evsel->priv);
170}