aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/ui/browsers/annotate.c
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2015-07-18 11:24:50 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-08-06 15:36:12 -0400
commit30e863bb6f708c0abd422fbb0e6b295f5ee6407b (patch)
tree61f2ba3ee89bb1162a3e2f4275194589c1ae97f0 /tools/perf/ui/browsers/annotate.c
parent57849998e2cd24d50295076a1bbd2f029e2d7c38 (diff)
perf annotate: Compute IPC and basic block cycles
Compute the IPC and the basic block cycles for the annotate display. IPC is computed by counting the instructions, and then dividing the accounted cycles by that count. The actual IPC computation can only be done at annotate time, because we need to parse the objdump output first to know the number of instructions in the basic block. The cycles/IPC are also put into the perf function annotation so that the display code can show them. Again basic block overlaps are not handled, with the longest winning, but there are some heuristics to hide the IPC when the longest is not the most common. v2: Compute IPC correctly. Signed-off-by: Andi Kleen <ak@linux.intel.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Link: http://lkml.kernel.org/r/1437233094-12844-6-git-send-email-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/ui/browsers/annotate.c')
-rw-r--r--tools/perf/ui/browsers/annotate.c73
1 files changed, 72 insertions, 1 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index 5995a8bd7c69..6ec179547f72 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -53,6 +53,7 @@ struct annotate_browser {
53 int max_jump_sources; 53 int max_jump_sources;
54 int nr_jumps; 54 int nr_jumps;
55 bool searching_backwards; 55 bool searching_backwards;
56 bool have_cycles;
56 u8 addr_width; 57 u8 addr_width;
57 u8 jumps_width; 58 u8 jumps_width;
58 u8 target_width; 59 u8 target_width;
@@ -390,7 +391,7 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,
390 max_percent = bpos->samples[i].percent; 391 max_percent = bpos->samples[i].percent;
391 } 392 }
392 393
393 if (max_percent < 0.01) { 394 if (max_percent < 0.01 && pos->ipc == 0) {
394 RB_CLEAR_NODE(&bpos->rb_node); 395 RB_CLEAR_NODE(&bpos->rb_node);
395 continue; 396 continue;
396 } 397 }
@@ -869,6 +870,75 @@ int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
869 return map_symbol__tui_annotate(&he->ms, evsel, hbt); 870 return map_symbol__tui_annotate(&he->ms, evsel, hbt);
870} 871}
871 872
873
874static unsigned count_insn(struct annotate_browser *browser, u64 start, u64 end)
875{
876 unsigned n_insn = 0;
877 u64 offset;
878
879 for (offset = start; offset <= end; offset++) {
880 if (browser->offsets[offset])
881 n_insn++;
882 }
883 return n_insn;
884}
885
886static void count_and_fill(struct annotate_browser *browser, u64 start, u64 end,
887 struct cyc_hist *ch)
888{
889 unsigned n_insn;
890 u64 offset;
891
892 n_insn = count_insn(browser, start, end);
893 if (n_insn && ch->num && ch->cycles) {
894 float ipc = n_insn / ((double)ch->cycles / (double)ch->num);
895
896 /* Hide data when there are too many overlaps. */
897 if (ch->reset >= 0x7fff || ch->reset >= ch->num / 2)
898 return;
899
900 for (offset = start; offset <= end; offset++) {
901 struct disasm_line *dl = browser->offsets[offset];
902
903 if (dl)
904 dl->ipc = ipc;
905 }
906 }
907}
908
909/*
910 * This should probably be in util/annotate.c to share with the tty
911 * annotate, but right now we need the per byte offsets arrays,
912 * which are only here.
913 */
914static void annotate__compute_ipc(struct annotate_browser *browser, size_t size,
915 struct symbol *sym)
916{
917 u64 offset;
918 struct annotation *notes = symbol__annotation(sym);
919
920 if (!notes->src || !notes->src->cycles_hist)
921 return;
922
923 pthread_mutex_lock(&notes->lock);
924 for (offset = 0; offset < size; ++offset) {
925 struct cyc_hist *ch;
926
927 ch = &notes->src->cycles_hist[offset];
928 if (ch && ch->cycles) {
929 struct disasm_line *dl;
930
931 if (ch->have_start)
932 count_and_fill(browser, ch->start, offset, ch);
933 dl = browser->offsets[offset];
934 if (dl && ch->num_aggr)
935 dl->cycles = ch->cycles_aggr / ch->num_aggr;
936 browser->have_cycles = true;
937 }
938 }
939 pthread_mutex_unlock(&notes->lock);
940}
941
872static void annotate_browser__mark_jump_targets(struct annotate_browser *browser, 942static void annotate_browser__mark_jump_targets(struct annotate_browser *browser,
873 size_t size) 943 size_t size)
874{ 944{
@@ -991,6 +1061,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
991 } 1061 }
992 1062
993 annotate_browser__mark_jump_targets(&browser, size); 1063 annotate_browser__mark_jump_targets(&browser, size);
1064 annotate__compute_ipc(&browser, size, sym);
994 1065
995 browser.addr_width = browser.target_width = browser.min_addr_width = hex_width(size); 1066 browser.addr_width = browser.target_width = browser.min_addr_width = hex_width(size);
996 browser.max_addr_width = hex_width(sym->end); 1067 browser.max_addr_width = hex_width(sym->end);