diff options
Diffstat (limited to 'tools/perf/builtin-stat.c')
-rw-r--r-- | tools/perf/builtin-stat.c | 74 |
1 files changed, 16 insertions, 58 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index dab347d7b01..e0f65fe6594 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -51,13 +51,13 @@ #include "util/evsel.h" #include "util/debug.h" #include "util/color.h" +#include "util/stat.h" #include "util/header.h" #include "util/cpumap.h" #include "util/thread.h" #include "util/thread_map.h" #include <sys/prctl.h> -#include <math.h> #include <locale.h> #define DEFAULT_SEPARATOR " " @@ -199,11 +199,6 @@ static int output_fd; static volatile int done = 0; -struct stats -{ - double n, mean, M2; -}; - struct perf_stat { struct stats res_stats[3]; }; @@ -220,48 +215,14 @@ static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) evsel->priv = NULL; } -static void update_stats(struct stats *stats, u64 val) +static inline struct cpu_map *perf_evsel__cpus(struct perf_evsel *evsel) { - double delta; - - stats->n++; - delta = val - stats->mean; - stats->mean += delta / stats->n; - stats->M2 += delta*(val - stats->mean); + return (evsel->cpus && !target.cpu_list) ? evsel->cpus : evsel_list->cpus; } -static 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) - * - */ -static double stddev_stats(struct stats *stats) +static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel) { - double variance, variance_mean; - - if (!stats->n) - return 0.0; - - variance = stats->M2 / (stats->n - 1); - variance_mean = variance / stats->n; - - return sqrt(variance_mean); + return perf_evsel__cpus(evsel)->nr; } static struct stats runtime_nsecs_stats[MAX_NR_CPUS]; @@ -295,7 +256,7 @@ retry: evsel->attr.exclude_guest = evsel->attr.exclude_host = 0; if (perf_target__has_cpu(&target)) { - ret = perf_evsel__open_per_cpu(evsel, evsel_list->cpus); + ret = perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel)); if (ret) goto check_ret; return 0; @@ -376,7 +337,7 @@ static int read_counter_aggr(struct perf_evsel *counter) u64 *count = counter->counts->aggr.values; int i; - if (__perf_evsel__read(counter, evsel_list->cpus->nr, + if (__perf_evsel__read(counter, perf_evsel__nr_cpus(counter), evsel_list->threads->nr, scale) < 0) return -1; @@ -405,7 +366,7 @@ static int read_counter(struct perf_evsel *counter) u64 *count; int cpu; - for (cpu = 0; cpu < evsel_list->cpus->nr; cpu++) { + for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { if (__perf_evsel__read_on_cpu(counter, cpu, 0, scale) < 0) return -1; @@ -544,12 +505,12 @@ static int run_perf_stat(int argc __maybe_unused, const char **argv) if (no_aggr) { list_for_each_entry(counter, &evsel_list->entries, node) { read_counter(counter); - perf_evsel__close_fd(counter, evsel_list->cpus->nr, 1); + perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1); } } else { list_for_each_entry(counter, &evsel_list->entries, node) { read_counter_aggr(counter); - perf_evsel__close_fd(counter, evsel_list->cpus->nr, + perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), evsel_list->threads->nr); } } @@ -559,10 +520,7 @@ static int run_perf_stat(int argc __maybe_unused, const char **argv) static void print_noise_pct(double total, double avg) { - double pct = 0.0; - - if (avg) - pct = 100.0*total/avg; + double pct = rel_stddev_stats(total, avg); if (csv_output) fprintf(output, "%s%.2f%%", csv_sep, pct); @@ -590,7 +548,7 @@ static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg) if (no_aggr) sprintf(cpustr, "CPU%*d%s", csv_output ? 0 : -4, - evsel_list->cpus->map[cpu], csv_sep); + perf_evsel__cpus(evsel)->map[cpu], csv_sep); fprintf(output, fmt, cpustr, msecs, csv_sep, perf_evsel__name(evsel)); @@ -802,7 +760,7 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg) if (no_aggr) sprintf(cpustr, "CPU%*d%s", csv_output ? 0 : -4, - evsel_list->cpus->map[cpu], csv_sep); + perf_evsel__cpus(evsel)->map[cpu], csv_sep); else cpu = 0; @@ -963,14 +921,14 @@ static void print_counter(struct perf_evsel *counter) u64 ena, run, val; int cpu; - for (cpu = 0; cpu < evsel_list->cpus->nr; cpu++) { + for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { val = counter->counts->cpu[cpu].val; ena = counter->counts->cpu[cpu].ena; run = counter->counts->cpu[cpu].run; if (run == 0 || ena == 0) { fprintf(output, "CPU%*d%s%*s%s%*s", csv_output ? 0 : -4, - evsel_list->cpus->map[cpu], csv_sep, + perf_evsel__cpus(counter)->map[cpu], csv_sep, csv_output ? 0 : 18, counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, csv_sep, @@ -1269,7 +1227,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) list_for_each_entry(pos, &evsel_list->entries, node) { if (perf_evsel__alloc_stat_priv(pos) < 0 || - perf_evsel__alloc_counts(pos, evsel_list->cpus->nr) < 0) + perf_evsel__alloc_counts(pos, perf_evsel__nr_cpus(pos)) < 0) goto out_free_fd; } |