aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephane Eranian <eranian@google.com>2013-02-14 07:57:27 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-03-25 14:29:53 -0400
commit86ee6e18f6cb43ab0cb67347bda5b6f5b016121d (patch)
tree414e785b0ba86fc602ad286846cdfd9266568df6
parentebf3c675d7e4ba97568dd6daaa43b1af10046b29 (diff)
perf stat: Refactor aggregation code
Refactor aggregation code by introducing a single aggr_mode variable and an enum for aggregation. Also refactor cpumap code having to do with cpu to socket mappings. All in preparation for extended modes, such as cpu -> core. Also fix socket aggregation and ensure that sockets are printed in increasing order. Signed-off-by: Stephane Eranian <eranian@google.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1360846649-6411-2-git-send-email-eranian@google.com [ committer note: Fixup conflicts with a7e191c "--repeat forever" and acf2892 "Use perf_evlist__prepare/start_workload()" ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/builtin-stat.c207
-rw-r--r--tools/perf/util/cpumap.c40
2 files changed, 147 insertions, 100 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index ba0bdd87c279..ded34fc4df4f 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -68,7 +68,7 @@
68static void print_stat(int argc, const char **argv); 68static void print_stat(int argc, const char **argv);
69static void print_counter_aggr(struct perf_evsel *counter, char *prefix); 69static void print_counter_aggr(struct perf_evsel *counter, char *prefix);
70static void print_counter(struct perf_evsel *counter, char *prefix); 70static void print_counter(struct perf_evsel *counter, char *prefix);
71static void print_aggr_socket(char *prefix); 71static void print_aggr(char *prefix);
72 72
73static struct perf_evlist *evsel_list; 73static struct perf_evlist *evsel_list;
74 74
@@ -76,11 +76,16 @@ static struct perf_target target = {
76 .uid = UINT_MAX, 76 .uid = UINT_MAX,
77}; 77};
78 78
79enum aggr_mode {
80 AGGR_NONE,
81 AGGR_GLOBAL,
82 AGGR_SOCKET,
83};
84
79static int run_count = 1; 85static int run_count = 1;
80static bool no_inherit = false; 86static bool no_inherit = false;
81static bool scale = true; 87static bool scale = true;
82static bool no_aggr = false; 88static enum aggr_mode aggr_mode = AGGR_GLOBAL;
83static bool aggr_socket = false;
84static pid_t child_pid = -1; 89static pid_t child_pid = -1;
85static bool null_run = false; 90static bool null_run = false;
86static int detailed_run = 0; 91static int detailed_run = 0;
@@ -96,7 +101,8 @@ static bool sync_run = false;
96static unsigned int interval = 0; 101static unsigned int interval = 0;
97static bool forever = false; 102static bool forever = false;
98static struct timespec ref_time; 103static struct timespec ref_time;
99static struct cpu_map *sock_map; 104static struct cpu_map *aggr_map;
105static int (*aggr_get_id)(struct cpu_map *m, int cpu);
100 106
101static volatile int done = 0; 107static volatile int done = 0;
102 108
@@ -355,41 +361,51 @@ static void print_interval(void)
355 struct timespec ts, rs; 361 struct timespec ts, rs;
356 char prefix[64]; 362 char prefix[64];
357 363
358 if (no_aggr) { 364 if (aggr_mode == AGGR_GLOBAL) {
359 list_for_each_entry(counter, &evsel_list->entries, node) { 365 list_for_each_entry(counter, &evsel_list->entries, node) {
360 ps = counter->priv; 366 ps = counter->priv;
361 memset(ps->res_stats, 0, sizeof(ps->res_stats)); 367 memset(ps->res_stats, 0, sizeof(ps->res_stats));
362 read_counter(counter); 368 read_counter_aggr(counter);
363 } 369 }
364 } else { 370 } else {
365 list_for_each_entry(counter, &evsel_list->entries, node) { 371 list_for_each_entry(counter, &evsel_list->entries, node) {
366 ps = counter->priv; 372 ps = counter->priv;
367 memset(ps->res_stats, 0, sizeof(ps->res_stats)); 373 memset(ps->res_stats, 0, sizeof(ps->res_stats));
368 read_counter_aggr(counter); 374 read_counter(counter);
369 } 375 }
370 } 376 }
377
371 clock_gettime(CLOCK_MONOTONIC, &ts); 378 clock_gettime(CLOCK_MONOTONIC, &ts);
372 diff_timespec(&rs, &ts, &ref_time); 379 diff_timespec(&rs, &ts, &ref_time);
373 sprintf(prefix, "%6lu.%09lu%s", rs.tv_sec, rs.tv_nsec, csv_sep); 380 sprintf(prefix, "%6lu.%09lu%s", rs.tv_sec, rs.tv_nsec, csv_sep);
374 381
375 if (num_print_interval == 0 && !csv_output) { 382 if (num_print_interval == 0 && !csv_output) {
376 if (aggr_socket) 383 switch (aggr_mode) {
384 case AGGR_SOCKET:
377 fprintf(output, "# time socket cpus counts events\n"); 385 fprintf(output, "# time socket cpus counts events\n");
378 else if (no_aggr) 386 break;
387 case AGGR_NONE:
379 fprintf(output, "# time CPU counts events\n"); 388 fprintf(output, "# time CPU counts events\n");
380 else 389 break;
390 case AGGR_GLOBAL:
391 default:
381 fprintf(output, "# time counts events\n"); 392 fprintf(output, "# time counts events\n");
393 }
382 } 394 }
383 395
384 if (++num_print_interval == 25) 396 if (++num_print_interval == 25)
385 num_print_interval = 0; 397 num_print_interval = 0;
386 398
387 if (aggr_socket) 399 switch (aggr_mode) {
388 print_aggr_socket(prefix); 400 case AGGR_SOCKET:
389 else if (no_aggr) { 401 print_aggr(prefix);
402 break;
403 case AGGR_NONE:
390 list_for_each_entry(counter, &evsel_list->entries, node) 404 list_for_each_entry(counter, &evsel_list->entries, node)
391 print_counter(counter, prefix); 405 print_counter(counter, prefix);
392 } else { 406 break;
407 case AGGR_GLOBAL:
408 default:
393 list_for_each_entry(counter, &evsel_list->entries, node) 409 list_for_each_entry(counter, &evsel_list->entries, node)
394 print_counter_aggr(counter, prefix); 410 print_counter_aggr(counter, prefix);
395 } 411 }
@@ -412,12 +428,6 @@ static int __run_perf_stat(int argc, const char **argv)
412 ts.tv_nsec = 0; 428 ts.tv_nsec = 0;
413 } 429 }
414 430
415 if (aggr_socket
416 && cpu_map__build_socket_map(evsel_list->cpus, &sock_map)) {
417 perror("cannot build socket map");
418 return -1;
419 }
420
421 if (forks) { 431 if (forks) {
422 if (perf_evlist__prepare_workload(evsel_list, &target, argv, 432 if (perf_evlist__prepare_workload(evsel_list, &target, argv,
423 false, false) < 0) { 433 false, false) < 0) {
@@ -493,17 +503,17 @@ static int __run_perf_stat(int argc, const char **argv)
493 503
494 update_stats(&walltime_nsecs_stats, t1 - t0); 504 update_stats(&walltime_nsecs_stats, t1 - t0);
495 505
496 if (no_aggr) { 506 if (aggr_mode == AGGR_GLOBAL) {
497 list_for_each_entry(counter, &evsel_list->entries, node) {
498 read_counter(counter);
499 perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1);
500 }
501 } else {
502 list_for_each_entry(counter, &evsel_list->entries, node) { 507 list_for_each_entry(counter, &evsel_list->entries, node) {
503 read_counter_aggr(counter); 508 read_counter_aggr(counter);
504 perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 509 perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
505 thread_map__nr(evsel_list->threads)); 510 thread_map__nr(evsel_list->threads));
506 } 511 }
512 } else {
513 list_for_each_entry(counter, &evsel_list->entries, node) {
514 read_counter(counter);
515 perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1);
516 }
507 } 517 }
508 518
509 return WEXITSTATUS(status); 519 return WEXITSTATUS(status);
@@ -556,26 +566,37 @@ static void print_noise(struct perf_evsel *evsel, double avg)
556 print_noise_pct(stddev_stats(&ps->res_stats[0]), avg); 566 print_noise_pct(stddev_stats(&ps->res_stats[0]), avg);
557} 567}
558 568
559static void nsec_printout(int cpu, int nr, struct perf_evsel *evsel, double avg) 569static void aggr_printout(struct perf_evsel *evsel, int cpu, int nr)
560{ 570{
561 double msecs = avg / 1e6; 571 switch (aggr_mode) {
562 char cpustr[16] = { '\0', }; 572 case AGGR_SOCKET:
563 const char *fmt = csv_output ? "%s%.6f%s%s" : "%s%18.6f%s%-25s"; 573 fprintf(output, "S%*d%s%*d%s",
564
565 if (aggr_socket)
566 sprintf(cpustr, "S%*d%s%*d%s",
567 csv_output ? 0 : -5, 574 csv_output ? 0 : -5,
568 cpu, 575 cpu,