Skip to content

Commit 30e863b

Browse files
Andi Kleenacmel
authored andcommitted
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 <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Namhyung Kim <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 5784999 commit 30e863b

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

tools/perf/ui/browsers/annotate.c

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ struct annotate_browser {
5353
int max_jump_sources;
5454
int nr_jumps;
5555
bool searching_backwards;
56+
bool have_cycles;
5657
u8 addr_width;
5758
u8 jumps_width;
5859
u8 target_width;
@@ -390,7 +391,7 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,
390391
max_percent = bpos->samples[i].percent;
391392
}
392393

393-
if (max_percent < 0.01) {
394+
if (max_percent < 0.01 && pos->ipc == 0) {
394395
RB_CLEAR_NODE(&bpos->rb_node);
395396
continue;
396397
}
@@ -869,6 +870,75 @@ int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
869870
return map_symbol__tui_annotate(&he->ms, evsel, hbt);
870871
}
871872

873+
874+
static 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+
886+
static 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+
*/
914+
static 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+
872942
static void annotate_browser__mark_jump_targets(struct annotate_browser *browser,
873943
size_t size)
874944
{
@@ -991,6 +1061,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
9911061
}
9921062

9931063
annotate_browser__mark_jump_targets(&browser, size);
1064+
annotate__compute_ipc(&browser, size, sym);
9941065

9951066
browser.addr_width = browser.target_width = browser.min_addr_width = hex_width(size);
9961067
browser.max_addr_width = hex_width(sym->end);

tools/perf/util/annotate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ struct disasm_line {
5959
char *name;
6060
struct ins *ins;
6161
int line_nr;
62+
float ipc;
63+
u64 cycles;
6264
struct ins_operands ops;
6365
};
6466

0 commit comments

Comments
 (0)