diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-05-14 13:19:35 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-05-14 13:19:35 -0400 |
commit | c82ee828aa20487d254a5225d256cd422acee459 (patch) | |
tree | 6f8132442237bc4f2393e04a5f30b3711a8f91ca /tools/perf/util/hist.c | |
parent | cee75ac7ecc27084accdb9d9d6fde65a09f047ae (diff) |
perf report: Report number of events, not samples
Number of samples is meaningless after we switched to auto-freq, so
report the number of events, i.e. not the sum of the different periods,
but the number PERF_RECORD_SAMPLE emitted by the kernel.
While doing this I noticed that naming "count" to the sum of all the
event periods can be confusing, so rename it to .period, just like in
struct sample.data, so that we become more consistent.
This helps with the next step, that was to record in struct hist_entry
the number of sample events for each instance, we need that because we
use it to generate the number of events when applying filters to the
tree of hist entries like it is being done in the TUI report browser.
Suggested-by: Ingo Molnar <mingo@elte.hu>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/hist.c')
-rw-r--r-- | tools/perf/util/hist.c | 88 |
1 files changed, 47 insertions, 41 deletions
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index c59224518083..f75c5f62401c 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -9,21 +9,21 @@ struct callchain_param callchain_param = { | |||
9 | .min_percent = 0.5 | 9 | .min_percent = 0.5 |
10 | }; | 10 | }; |
11 | 11 | ||
12 | static void hist_entry__add_cpumode_count(struct hist_entry *self, | 12 | static void hist_entry__add_cpumode_period(struct hist_entry *self, |
13 | unsigned int cpumode, u64 count) | 13 | unsigned int cpumode, u64 period) |
14 | { | 14 | { |
15 | switch (cpumode) { | 15 | switch (cpumode) { |
16 | case PERF_RECORD_MISC_KERNEL: | 16 | case PERF_RECORD_MISC_KERNEL: |
17 | self->count_sys += count; | 17 | self->period_sys += period; |
18 | break; | 18 | break; |
19 | case PERF_RECORD_MISC_USER: | 19 | case PERF_RECORD_MISC_USER: |
20 | self->count_us += count; | 20 | self->period_us += period; |
21 | break; | 21 | break; |
22 | case PERF_RECORD_MISC_GUEST_KERNEL: | 22 | case PERF_RECORD_MISC_GUEST_KERNEL: |
23 | self->count_guest_sys += count; | 23 | self->period_guest_sys += period; |
24 | break; | 24 | break; |
25 | case PERF_RECORD_MISC_GUEST_USER: | 25 | case PERF_RECORD_MISC_GUEST_USER: |
26 | self->count_guest_us += count; | 26 | self->period_guest_us += period; |
27 | break; | 27 | break; |
28 | default: | 28 | default: |
29 | break; | 29 | break; |
@@ -31,7 +31,7 @@ static void hist_entry__add_cpumode_count(struct hist_entry *self, | |||
31 | } | 31 | } |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * histogram, sorted on item, collects counts | 34 | * histogram, sorted on item, collects periods |
35 | */ | 35 | */ |
36 | 36 | ||
37 | static struct hist_entry *hist_entry__new(struct hist_entry *template) | 37 | static struct hist_entry *hist_entry__new(struct hist_entry *template) |
@@ -41,6 +41,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) | |||
41 | 41 | ||
42 | if (self != NULL) { | 42 | if (self != NULL) { |
43 | *self = *template; | 43 | *self = *template; |
44 | self->nr_events = 1; | ||
44 | if (symbol_conf.use_callchain) | 45 | if (symbol_conf.use_callchain) |
45 | callchain_init(self->callchain); | 46 | callchain_init(self->callchain); |
46 | } | 47 | } |
@@ -57,7 +58,7 @@ static void hists__inc_nr_entries(struct hists *self, struct hist_entry *entry) | |||
57 | 58 | ||
58 | struct hist_entry *__hists__add_entry(struct hists *self, | 59 | struct hist_entry *__hists__add_entry(struct hists *self, |
59 | struct addr_location *al, | 60 | struct addr_location *al, |
60 | struct symbol *sym_parent, u64 count) | 61 | struct symbol *sym_parent, u64 period) |
61 | { | 62 | { |
62 | struct rb_node **p = &self->entries.rb_node; | 63 | struct rb_node **p = &self->entries.rb_node; |
63 | struct rb_node *parent = NULL; | 64 | struct rb_node *parent = NULL; |
@@ -70,7 +71,7 @@ struct hist_entry *__hists__add_entry(struct hists *self, | |||
70 | }, | 71 | }, |
71 | .ip = al->addr, | 72 | .ip = al->addr, |
72 | .level = al->level, | 73 | .level = al->level, |
73 | .count = count, | 74 | .period = period, |
74 | .parent = sym_parent, | 75 | .parent = sym_parent, |
75 | }; | 76 | }; |
76 | int cmp; | 77 | int cmp; |
@@ -82,7 +83,8 @@ struct hist_entry *__hists__add_entry(struct hists *self, | |||
82 | cmp = hist_entry__cmp(&entry, he); | 83 | cmp = hist_entry__cmp(&entry, he); |
83 | 84 | ||
84 | if (!cmp) { | 85 | if (!cmp) { |
85 | he->count += count; | 86 | he->period += period; |
87 | ++he->nr_events; | ||
86 | goto out; | 88 | goto out; |
87 | } | 89 | } |
88 | 90 | ||
@@ -99,7 +101,7 @@ struct hist_entry *__hists__add_entry(struct hists *self, | |||
99 | rb_insert_color(&he->rb_node, &self->entries); | 101 | rb_insert_color(&he->rb_node, &self->entries); |
100 | hists__inc_nr_entries(self, he); | 102 | hists__inc_nr_entries(self, he); |
101 | out: | 103 | out: |
102 | hist_entry__add_cpumode_count(he, al->cpumode, count); | 104 | hist_entry__add_cpumode_period(he, al->cpumode, period); |
103 | return he; | 105 | return he; |
104 | } | 106 | } |
105 | 107 | ||
@@ -160,7 +162,7 @@ static bool collapse__insert_entry(struct rb_root *root, struct hist_entry *he) | |||
160 | cmp = hist_entry__collapse(iter, he); | 162 | cmp = hist_entry__collapse(iter, he); |
161 | 163 | ||
162 | if (!cmp) { | 164 | if (!cmp) { |
163 | iter->count += he->count; | 165 | iter->period += he->period; |
164 | hist_entry__free(he); | 166 | hist_entry__free(he); |
165 | return false; | 167 | return false; |
166 | } | 168 | } |
@@ -203,7 +205,7 @@ void hists__collapse_resort(struct hists *self) | |||
203 | } | 205 | } |
204 | 206 | ||
205 | /* | 207 | /* |
206 | * reverse the map, sort on count. | 208 | * reverse the map, sort on period. |
207 | */ | 209 | */ |
208 | 210 | ||
209 | static void __hists__insert_output_entry(struct rb_root *entries, | 211 | static void __hists__insert_output_entry(struct rb_root *entries, |
@@ -222,7 +224,7 @@ static void __hists__insert_output_entry(struct rb_root *entries, | |||
222 | parent = *p; | 224 | parent = *p; |
223 | iter = rb_entry(parent, struct hist_entry, rb_node); | 225 | iter = rb_entry(parent, struct hist_entry, rb_node); |
224 | 226 | ||
225 | if (he->count > iter->count) | 227 | if (he->period > iter->period) |
226 | p = &(*p)->rb_left; | 228 | p = &(*p)->rb_left; |
227 | else | 229 | else |
228 | p = &(*p)->rb_right; | 230 | p = &(*p)->rb_right; |
@@ -288,7 +290,7 @@ static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask, | |||
288 | } | 290 | } |
289 | 291 | ||
290 | static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, | 292 | static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, |
291 | int depth, int depth_mask, int count, | 293 | int depth, int depth_mask, int period, |
292 | u64 total_samples, int hits, | 294 | u64 total_samples, int hits, |
293 | int left_margin) | 295 | int left_margin) |
294 | { | 296 | { |
@@ -301,7 +303,7 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, | |||
301 | ret += fprintf(fp, "|"); | 303 | ret += fprintf(fp, "|"); |
302 | else | 304 | else |
303 | ret += fprintf(fp, " "); | 305 | ret += fprintf(fp, " "); |
304 | if (!count && i == depth - 1) { | 306 | if (!period && i == depth - 1) { |
305 | double percent; | 307 | double percent; |
306 | 308 | ||
307 | percent = hits * 100.0 / total_samples; | 309 | percent = hits * 100.0 / total_samples; |
@@ -516,7 +518,7 @@ int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size, | |||
516 | long displacement, bool color, u64 session_total) | 518 | long displacement, bool color, u64 session_total) |
517 | { | 519 | { |
518 | struct sort_entry *se; | 520 | struct sort_entry *se; |
519 | u64 count, total, count_sys, count_us, count_guest_sys, count_guest_us; | 521 | u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us; |
520 | const char *sep = symbol_conf.field_sep; | 522 | const char *sep = symbol_conf.field_sep; |
521 | int ret; | 523 | int ret; |
522 | 524 | ||
@@ -524,57 +526,57 @@ int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size, | |||
524 | return 0; | 526 | return 0; |
525 | 527 | ||
526 | if (pair_hists) { | 528 | if (pair_hists) { |
527 | count = self->pair ? self->pair->count : 0; | 529 | period = self->pair ? self->pair->period : 0; |
528 | total = pair_hists->stats.total_period; | 530 | total = pair_hists->stats.total_period; |
529 | count_sys = self->pair ? self->pair->count_sys : 0; | 531 | period_sys = self->pair ? self->pair->period_sys : 0; |
530 | count_us = self->pair ? self->pair->count_us : 0; | 532 | period_us = self->pair ? self->pair->period_us : 0; |
531 | count_guest_sys = self->pair ? self->pair->count_guest_sys : 0; | 533 | period_guest_sys = self->pair ? self->pair->period_guest_sys : 0; |
532 | count_guest_us = self->pair ? self->pair->count_guest_us : 0; | 534 | period_guest_us = self->pair ? self->pair->period_guest_us : 0; |
533 | } else { | 535 | } else { |
534 | count = self->count; | 536 | period = self->period; |
535 | total = session_total; | 537 | total = session_total; |
536 | count_sys = self->count_sys; | 538 | period_sys = self->period_sys; |
537 | count_us = self->count_us; | 539 | period_us = self->period_us; |
538 | count_guest_sys = self->count_guest_sys; | 540 | period_guest_sys = self->period_guest_sys; |
539 | count_guest_us = self->count_guest_us; | 541 | period_guest_us = self->period_guest_us; |
540 | } | 542 | } |
541 | 543 | ||
542 | if (total) { | 544 | if (total) { |
543 | if (color) | 545 | if (color) |
544 | ret = percent_color_snprintf(s, size, | 546 | ret = percent_color_snprintf(s, size, |
545 | sep ? "%.2f" : " %6.2f%%", | 547 | sep ? "%.2f" : " %6.2f%%", |
546 | (count * 100.0) / total); | 548 | (period * 100.0) / total); |
547 | else | 549 | else |
548 | ret = snprintf(s, size, sep ? "%.2f" : " %6.2f%%", | 550 | ret = snprintf(s, size, sep ? "%.2f" : " %6.2f%%", |
549 | (count * 100.0) / total); | 551 | (period * 100.0) / total); |
550 | if (symbol_conf.show_cpu_utilization) { | 552 | if (symbol_conf.show_cpu_utilization) { |
551 | ret += percent_color_snprintf(s + ret, size - ret, | 553 | ret += percent_color_snprintf(s + ret, size - ret, |
552 | sep ? "%.2f" : " %6.2f%%", | 554 | sep ? "%.2f" : " %6.2f%%", |
553 | (count_sys * 100.0) / total); | 555 | (period_sys * 100.0) / total); |
554 | ret += percent_color_snprintf(s + ret, size - ret, | 556 | ret += percent_color_snprintf(s + ret, size - ret, |
555 | sep ? "%.2f" : " %6.2f%%", | 557 | sep ? "%.2f" : " %6.2f%%", |
556 | (count_us * 100.0) / total); | 558 | (period_us * 100.0) / total); |
557 | if (perf_guest) { | 559 | if (perf_guest) { |
558 | ret += percent_color_snprintf(s + ret, | 560 | ret += percent_color_snprintf(s + ret, |
559 | size - ret, | 561 | size - ret, |
560 | sep ? "%.2f" : " %6.2f%%", | 562 | sep ? "%.2f" : " %6.2f%%", |
561 | (count_guest_sys * 100.0) / | 563 | (period_guest_sys * 100.0) / |
562 | total); | 564 | total); |
563 | ret += percent_color_snprintf(s + ret, | 565 | ret += percent_color_snprintf(s + ret, |
564 | size - ret, | 566 | size - ret, |
565 | sep ? "%.2f" : " %6.2f%%", | 567 | sep ? "%.2f" : " %6.2f%%", |
566 | (count_guest_us * 100.0) / | 568 | (period_guest_us * 100.0) / |
567 | total); | 569 | total); |
568 | } | 570 | } |
569 | } | 571 | } |
570 | } else | 572 | } else |
571 | ret = snprintf(s, size, sep ? "%lld" : "%12lld ", count); | 573 | ret = snprintf(s, size, sep ? "%lld" : "%12lld ", period); |
572 | 574 | ||
573 | if (symbol_conf.show_nr_samples) { | 575 | if (symbol_conf.show_nr_samples) { |
574 | if (sep) | 576 | if (sep) |
575 | ret += snprintf(s + ret, size - ret, "%c%lld", *sep, count); | 577 | ret += snprintf(s + ret, size - ret, "%c%lld", *sep, period); |
576 | else | 578 | else |
577 | ret += snprintf(s + ret, size - ret, "%11lld", count); | 579 | ret += snprintf(s + ret, size - ret, "%11lld", period); |
578 | } | 580 | } |
579 | 581 | ||
580 | if (pair_hists) { | 582 | if (pair_hists) { |
@@ -582,9 +584,9 @@ int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size, | |||
582 | double old_percent = 0, new_percent = 0, diff; | 584 | double old_percent = 0, new_percent = 0, diff; |
583 | 585 | ||
584 | if (total > 0) | 586 | if (total > 0) |
585 | old_percent = (count * 100.0) / total; | 587 | old_percent = (period * 100.0) / total; |
586 | if (session_total > 0) | 588 | if (session_total > 0) |
587 | new_percent = (self->count * 100.0) / session_total; | 589 | new_percent = (self->period * 100.0) / session_total; |
588 | 590 | ||
589 | diff = new_percent - old_percent; | 591 | diff = new_percent - old_percent; |
590 | 592 | ||
@@ -796,6 +798,7 @@ void hists__filter_by_dso(struct hists *self, const struct dso *dso) | |||
796 | struct rb_node *nd; | 798 | struct rb_node *nd; |
797 | 799 | ||
798 | self->nr_entries = self->stats.total_period = 0; | 800 | self->nr_entries = self->stats.total_period = 0; |
801 | self->stats.nr_events[PERF_RECORD_SAMPLE] = 0; | ||
799 | self->max_sym_namelen = 0; | 802 | self->max_sym_namelen = 0; |
800 | 803 | ||
801 | for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { | 804 | for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { |
@@ -812,7 +815,8 @@ void hists__filter_by_dso(struct hists *self, const struct dso *dso) | |||
812 | h->filtered &= ~(1 << HIST_FILTER__DSO); | 815 | h->filtered &= ~(1 << HIST_FILTER__DSO); |
813 | if (!h->filtered) { | 816 | if (!h->filtered) { |
814 | ++self->nr_entries; | 817 | ++self->nr_entries; |
815 | self->stats.total_period += h->count; | 818 | self->stats.total_period += h->period; |
819 | self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events; | ||
816 | if (h->ms.sym && | 820 | if (h->ms.sym && |
817 | self->max_sym_namelen < h->ms.sym->namelen) | 821 | self->max_sym_namelen < h->ms.sym->namelen) |
818 | self->max_sym_namelen = h->ms.sym->namelen; | 822 | self->max_sym_namelen = h->ms.sym->namelen; |
@@ -825,6 +829,7 @@ void hists__filter_by_thread(struct hists *self, const struct thread *thread) | |||
825 | struct rb_node *nd; | 829 | struct rb_node *nd; |
826 | 830 | ||
827 | self->nr_entries = self->stats.total_period = 0; | 831 | self->nr_entries = self->stats.total_period = 0; |
832 | self->stats.nr_events[PERF_RECORD_SAMPLE] = 0; | ||
828 | self->max_sym_namelen = 0; | 833 | self->max_sym_namelen = 0; |
829 | 834 | ||
830 | for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { | 835 | for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { |
@@ -837,7 +842,8 @@ void hists__filter_by_thread(struct hists *self, const struct thread *thread) | |||
837 | h->filtered &= ~(1 << HIST_FILTER__THREAD); | 842 | h->filtered &= ~(1 << HIST_FILTER__THREAD); |
838 | if (!h->filtered) { | 843 | if (!h->filtered) { |
839 | ++self->nr_entries; | 844 | ++self->nr_entries; |
840 | self->stats.total_period += h->count; | 845 | self->stats.total_period += h->period; |
846 | self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events; | ||
841 | if (h->ms.sym && | 847 | if (h->ms.sym && |
842 | self->max_sym_namelen < h->ms.sym->namelen) | 848 | self->max_sym_namelen < h->ms.sym->namelen) |
843 | self->max_sym_namelen = h->ms.sym->namelen; | 849 | self->max_sym_namelen = h->ms.sym->namelen; |
@@ -881,7 +887,7 @@ int hist_entry__inc_addr_samples(struct hist_entry *self, u64 ip) | |||
881 | h->sum++; | 887 | h->sum++; |
882 | h->ip[offset]++; | 888 | h->ip[offset]++; |
883 | 889 | ||
884 | pr_debug3("%#Lx %s: count++ [ip: %#Lx, %#Lx] => %Ld\n", self->ms.sym->start, | 890 | pr_debug3("%#Lx %s: period++ [ip: %#Lx, %#Lx] => %Ld\n", self->ms.sym->start, |
885 | self->ms.sym->name, ip, ip - self->ms.sym->start, h->ip[offset]); | 891 | self->ms.sym->name, ip, ip - self->ms.sym->start, h->ip[offset]); |
886 | return 0; | 892 | return 0; |
887 | } | 893 | } |