diff options
-rw-r--r-- | tools/perf/builtin-stat.c | 84 |
1 files changed, 27 insertions, 57 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 31ffc4d3ba60..9c6377f7152f 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -62,8 +62,6 @@ static struct perf_counter_attr default_attrs[] = { | |||
62 | 62 | ||
63 | }; | 63 | }; |
64 | 64 | ||
65 | #define MAX_RUN 100 | ||
66 | |||
67 | static int system_wide = 0; | 65 | static int system_wide = 0; |
68 | static unsigned int nr_cpus = 0; | 66 | static unsigned int nr_cpus = 0; |
69 | static int run_idx = 0; | 67 | static int run_idx = 0; |
@@ -76,12 +74,8 @@ static int null_run = 0; | |||
76 | 74 | ||
77 | static int fd[MAX_NR_CPUS][MAX_COUNTERS]; | 75 | static int fd[MAX_NR_CPUS][MAX_COUNTERS]; |
78 | 76 | ||
79 | static u64 runtime_nsecs[MAX_RUN]; | 77 | static u64 event_res[MAX_COUNTERS][3]; |
80 | static u64 walltime_nsecs[MAX_RUN]; | 78 | static u64 event_scaled[MAX_COUNTERS]; |
81 | static u64 runtime_cycles[MAX_RUN]; | ||
82 | |||
83 | static u64 event_res[MAX_RUN][MAX_COUNTERS][3]; | ||
84 | static u64 event_scaled[MAX_RUN][MAX_COUNTERS]; | ||
85 | 79 | ||
86 | struct stats | 80 | struct stats |
87 | { | 81 | { |
@@ -89,6 +83,14 @@ struct stats | |||
89 | double sum_sq; | 83 | double sum_sq; |
90 | }; | 84 | }; |
91 | 85 | ||
86 | static void update_stats(struct stats *stats, u64 val) | ||
87 | { | ||
88 | double sq = val; | ||
89 | |||
90 | stats->sum += val; | ||
91 | stats->sum_sq += sq * sq; | ||
92 | } | ||
93 | |||
92 | static double avg_stats(struct stats *stats) | 94 | static double avg_stats(struct stats *stats) |
93 | { | 95 | { |
94 | return stats->sum / run_count; | 96 | return stats->sum / run_count; |
@@ -167,8 +169,9 @@ static void read_counter(int counter) | |||
167 | unsigned int cpu; | 169 | unsigned int cpu; |
168 | size_t res, nv; | 170 | size_t res, nv; |
169 | int scaled; | 171 | int scaled; |
172 | int i; | ||
170 | 173 | ||
171 | count = event_res[run_idx][counter]; | 174 | count = event_res[counter]; |
172 | 175 | ||
173 | count[0] = count[1] = count[2] = 0; | 176 | count[0] = count[1] = count[2] = 0; |
174 | 177 | ||
@@ -193,24 +196,33 @@ static void read_counter(int counter) | |||
193 | scaled = 0; | 196 | scaled = 0; |
194 | if (scale) { | 197 | if (scale) { |
195 | if (count[2] == 0) { | 198 | if (count[2] == 0) { |
196 | event_scaled[run_idx][counter] = -1; | 199 | event_scaled[counter] = -1; |
197 | count[0] = 0; | 200 | count[0] = 0; |
198 | return; | 201 | return; |
199 | } | 202 | } |
200 | 203 | ||
201 | if (count[2] < count[1]) { | 204 | if (count[2] < count[1]) { |
202 | event_scaled[run_idx][counter] = 1; | 205 | event_scaled[counter] = 1; |
203 | count[0] = (unsigned long long) | 206 | count[0] = (unsigned long long) |
204 | ((double)count[0] * count[1] / count[2] + 0.5); | 207 | ((double)count[0] * count[1] / count[2] + 0.5); |
205 | } | 208 | } |
206 | } | 209 | } |
210 | |||
211 | for (i = 0; i < 3; i++) | ||
212 | update_stats(&event_res_stats[counter][i], count[i]); | ||
213 | |||
214 | if (verbose) { | ||
215 | fprintf(stderr, "%s: %Ld %Ld %Ld\n", event_name(counter), | ||
216 | count[0], count[1], count[2]); | ||
217 | } | ||
218 | |||
207 | /* | 219 | /* |
208 | * Save the full runtime - to allow normalization during printout: | 220 | * Save the full runtime - to allow normalization during printout: |
209 | */ | 221 | */ |
210 | if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter)) | 222 | if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter)) |
211 | runtime_nsecs[run_idx] = count[0]; | 223 | update_stats(&runtime_nsecs_stats, count[0]); |
212 | if (MATCH_EVENT(HARDWARE, HW_CPU_CYCLES, counter)) | 224 | if (MATCH_EVENT(HARDWARE, HW_CPU_CYCLES, counter)) |
213 | runtime_cycles[run_idx] = count[0]; | 225 | update_stats(&runtime_cycles_stats, count[0]); |
214 | } | 226 | } |
215 | 227 | ||
216 | static int run_perf_stat(int argc __used, const char **argv) | 228 | static int run_perf_stat(int argc __used, const char **argv) |
@@ -284,7 +296,7 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
284 | 296 | ||
285 | t1 = rdclock(); | 297 | t1 = rdclock(); |
286 | 298 | ||
287 | walltime_nsecs[run_idx] = t1 - t0; | 299 | update_stats(&walltime_nsecs_stats, t1 - t0); |
288 | 300 | ||
289 | for (counter = 0; counter < nr_counters; counter++) | 301 | for (counter = 0; counter < nr_counters; counter++) |
290 | read_counter(counter); | 302 | read_counter(counter); |
@@ -361,52 +373,10 @@ static void print_counter(int counter) | |||
361 | fprintf(stderr, "\n"); | 373 | fprintf(stderr, "\n"); |
362 | } | 374 | } |
363 | 375 | ||
364 | static void update_stats(const char *name, int idx, struct stats *stats, u64 *val) | ||
365 | { | ||
366 | double sq = *val; | ||
367 | |||
368 | stats->sum += *val; | ||
369 | stats->sum_sq += sq * sq; | ||
370 | |||
371 | if (verbose > 1) | ||
372 | fprintf(stderr, "debug: %20s[%d]: %Ld\n", name, idx, *val); | ||
373 | } | ||
374 | |||
375 | /* | ||
376 | * Calculate the averages and noises: | ||
377 | */ | ||
378 | static void calc_avg(void) | ||
379 | { | ||
380 | int i, j; | ||
381 | |||
382 | if (verbose > 1) | ||
383 | fprintf(stderr, "\n"); | ||
384 | |||
385 | for (i = 0; i < run_count; i++) { | ||
386 | update_stats("runtime", 0, &runtime_nsecs_stats, runtime_nsecs + i); | ||
387 | update_stats("walltime", 0, &walltime_nsecs_stats, walltime_nsecs + i); | ||
388 | update_stats("runtime_cycles", 0, &runtime_cycles_stats, runtime_cycles + i); | ||
389 | |||
390 | for (j = 0; j < nr_counters; j++) { | ||
391 | update_stats("counter/0", j, | ||
392 | event_res_stats[j]+0, event_res[i][j]+0); | ||
393 | update_stats("counter/1", j, | ||
394 | event_res_stats[j]+1, event_res[i][j]+1); | ||
395 | update_stats("counter/2", j, | ||
396 | event_res_stats[j]+2, event_res[i][j]+2); | ||
397 | if (event_scaled[i][j] != (u64)-1) | ||
398 | update_stats("scaled", j, | ||
399 | event_scaled_stats + j, event_scaled[i]+j); | ||
400 | } | ||
401 | } | ||
402 | } | ||
403 | |||
404 | static void print_stat(int argc, const char **argv) | 376 | static void print_stat(int argc, const char **argv) |
405 | { | 377 | { |
406 | int i, counter; | 378 | int i, counter; |
407 | 379 | ||
408 | calc_avg(); | ||
409 | |||
410 | fflush(stdout); | 380 | fflush(stdout); |
411 | 381 | ||
412 | fprintf(stderr, "\n"); | 382 | fprintf(stderr, "\n"); |
@@ -484,7 +454,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
484 | PARSE_OPT_STOP_AT_NON_OPTION); | 454 | PARSE_OPT_STOP_AT_NON_OPTION); |
485 | if (!argc) | 455 | if (!argc) |
486 | usage_with_options(stat_usage, options); | 456 | usage_with_options(stat_usage, options); |
487 | if (run_count <= 0 || run_count > MAX_RUN) | 457 | if (run_count <= 0) |
488 | usage_with_options(stat_usage, options); | 458 | usage_with_options(stat_usage, options); |
489 | 459 | ||
490 | /* Set attrs and nr_counters if no event is selected and !null_run */ | 460 | /* Set attrs and nr_counters if no event is selected and !null_run */ |