perf stat: Fix multi-run stats
[firefly-linux-kernel-4.4.55.git] / tools / perf / builtin-stat.c
index 6d3eeac1ea257b47c898dae49c6336c35c4c43f4..52c176cc683ec4c7b5bffbec552c4460b705208f 100644 (file)
@@ -59,42 +59,28 @@ static struct perf_counter_attr default_attrs[MAX_COUNTERS] = {
 
 };
 
+#define MAX_RUN                        100
+
 static int                     system_wide                     =  0;
-static int                     inherit                         =  1;
 static int                     verbose                         =  0;
-
-static int                     fd[MAX_NR_CPUS][MAX_COUNTERS];
-
-static int                     target_pid                      = -1;
 static int                     nr_cpus                         =  0;
-static unsigned int            page_size;
+static int                     run_idx                         =  0;
 
+static int                     run_count                       =  1;
+static int                     inherit                         =  1;
 static int                     scale                           =  1;
+static int                     target_pid                      = -1;
+static int                     null_run                        =  0;
 
-static const unsigned int default_count[] = {
-       1000000,
-       1000000,
-         10000,
-         10000,
-       1000000,
-         10000,
-};
-
-#define MAX_RUN 100
-
-static int                     run_count               =  1;
-static int                     run_idx                 =  0;
-
-static u64                     event_res[MAX_RUN][MAX_COUNTERS][3];
-static u64                     event_scaled[MAX_RUN][MAX_COUNTERS];
-
-//static u64                   event_hist[MAX_RUN][MAX_COUNTERS][3];
-
+static int                     fd[MAX_NR_CPUS][MAX_COUNTERS];
 
 static u64                     runtime_nsecs[MAX_RUN];
 static u64                     walltime_nsecs[MAX_RUN];
 static u64                     runtime_cycles[MAX_RUN];
 
+static u64                     event_res[MAX_RUN][MAX_COUNTERS][3];
+static u64                     event_scaled[MAX_RUN][MAX_COUNTERS];
+
 static u64                     event_res_avg[MAX_COUNTERS][3];
 static u64                     event_res_noise[MAX_COUNTERS][3];
 
@@ -109,6 +95,9 @@ static u64                   walltime_nsecs_noise;
 static u64                     runtime_cycles_avg;
 static u64                     runtime_cycles_noise;
 
+#define ERR_PERF_OPEN \
+"Error: counter %d, sys_perf_counter_open() syscall returned with %d (%s)\n"
+
 static void create_perf_stat_counter(int counter)
 {
        struct perf_counter_attr *attr = attrs + counter;
@@ -119,20 +108,20 @@ static void create_perf_stat_counter(int counter)
 
        if (system_wide) {
                int cpu;
-               for (cpu = 0; cpu < nr_cpus; cpu ++) {
+               for (cpu = 0; cpu < nr_cpus; cpu++) {
                        fd[cpu][counter] = sys_perf_counter_open(attr, -1, cpu, -1, 0);
-                       if (fd[cpu][counter] < 0 && verbose) {
-                               printf("Error: counter %d, sys_perf_counter_open() syscall returned with %d (%s)\n", counter, fd[cpu][counter], strerror(errno));
-                       }
+                       if (fd[cpu][counter] < 0 && verbose)
+                               fprintf(stderr, ERR_PERF_OPEN, counter,
+                                       fd[cpu][counter], strerror(errno));
                }
        } else {
                attr->inherit   = inherit;
                attr->disabled  = 1;
 
                fd[0][counter] = sys_perf_counter_open(attr, 0, -1, -1, 0);
-               if (fd[0][counter] < 0 && verbose) {
-                       printf("Error: counter %d, sys_perf_counter_open() syscall returned with %d (%s)\n", counter, fd[0][counter], strerror(errno));
-               }
+               if (fd[0][counter] < 0 && verbose)
+                       fprintf(stderr, ERR_PERF_OPEN, counter,
+                               fd[0][counter], strerror(errno));
        }
 }
 
@@ -168,7 +157,7 @@ static void read_counter(int counter)
        count[0] = count[1] = count[2] = 0;
 
        nv = scale ? 3 : 1;
-       for (cpu = 0; cpu < nr_cpus; cpu ++) {
+       for (cpu = 0; cpu < nr_cpus; cpu++) {
                if (fd[cpu][counter] < 0)
                        continue;
 
@@ -364,8 +353,11 @@ static void calc_avg(void)
                                event_res_avg[j]+1, event_res[i][j]+1);
                        update_avg("counter/2", j,
                                event_res_avg[j]+2, event_res[i][j]+2);
-                       update_avg("scaled", j,
-                               event_scaled_avg + j, event_scaled[i]+j);
+                       if (event_scaled[i][j] != -1)
+                               update_avg("scaled", j,
+                                       event_scaled_avg + j, event_scaled[i]+j);
+                       else
+                               event_scaled_avg[j] = -1;
                }
        }
        runtime_nsecs_avg /= run_count;
@@ -431,9 +423,13 @@ static void print_stat(int argc, const char **argv)
 
 
        fprintf(stderr, "\n");
-       fprintf(stderr, " %14.9f  seconds time elapsed.\n",
+       fprintf(stderr, " %14.9f  seconds time elapsed",
                        (double)walltime_nsecs_avg/1e9);
-       fprintf(stderr, "\n");
+       if (run_count > 1) {
+               fprintf(stderr, "   ( +- %7.3f%% )",
+                       100.0*(double)walltime_nsecs_noise/(double)walltime_nsecs_avg);
+       }
+       fprintf(stderr, "\n\n");
 }
 
 static volatile int signr = -1;
@@ -466,13 +462,15 @@ static const struct option options[] = {
        OPT_INTEGER('p', "pid", &target_pid,
                    "stat events on existing pid"),
        OPT_BOOLEAN('a', "all-cpus", &system_wide,
-                           "system-wide collection from all CPUs"),
+                   "system-wide collection from all CPUs"),
        OPT_BOOLEAN('S', "scale", &scale,
-                           "scale/normalize counters"),
+                   "scale/normalize counters"),
        OPT_BOOLEAN('v', "verbose", &verbose,
                    "be more verbose (show counter open errors, etc)"),
        OPT_INTEGER('r', "repeat", &run_count,
                    "repeat command and print average + stddev (max: 100)"),
+       OPT_BOOLEAN('n', "null", &null_run,
+                   "null run - dont start any counters"),
        OPT_END()
 };
 
@@ -480,8 +478,6 @@ int cmd_stat(int argc, const char **argv, const char *prefix)
 {
        int status;
 
-       page_size = sysconf(_SC_PAGE_SIZE);
-
        memcpy(attrs, default_attrs, sizeof(attrs));
 
        argc = parse_options(argc, argv, options, stat_usage, 0);
@@ -490,7 +486,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix)
        if (run_count <= 0 || run_count > MAX_RUN)
                usage_with_options(stat_usage, options);
 
-       if (!nr_counters)
+       if (!null_run && !nr_counters)
                nr_counters = 8;
 
        nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
@@ -511,7 +507,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix)
        status = 0;
        for (run_idx = 0; run_idx < run_count; run_idx++) {
                if (run_count != 1 && verbose)
-                       fprintf(stderr, "[ perf stat: executing run #%d ... ]\n", run_idx+1);
+                       fprintf(stderr, "[ perf stat: executing run #%d ... ]\n", run_idx + 1);
                status = run_perf_stat(argc, argv);
        }