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