Commit e6952dce authored by Kan Liang's avatar Kan Liang Committed by Arnaldo Carvalho de Melo
Browse files

perf annotate: Display the branch counter histogram



Display the branch counter histogram in the annotation view.

Press 'B' to display the branch counter's abbreviation list as well.

  Samples: 1M of events 'anon group { branch-instructions:ppp, branch-misses }',
  4000 Hz, Event count (approx.):
  f3  /home/sdp/test/tchain_edit [Percent: local period]
  Percent       │ IPC Cycle       Branch Counter (Average IPC: 1.39, IPC Coverage: 29.4%)
                │                                     0000000000401755 <f3>:
    0.00   0.00 │                                       endbr64
                │                                       push    %rbp
                │                                       mov     %rsp,%rbp
                │                                       movl    $0x0,-0x4(%rbp)
    0.00   0.00 │1.33     3          |A   |-   |      ↓ jmp     25
   11.03  11.03 │                                 11:   mov     -0x4(%rbp),%eax
                │                                       and     $0x1,%eax
                │                                       test    %eax,%eax
   17.13  17.13 │2.41     1          |A   |-   |      ↓ je      21
                │                                       addl    $0x1,-0x4(%rbp)
   21.84  21.84 │2.22     2          |AA  |-   |      ↓ jmp     25
   17.13  17.13 │                                 21:   addl    $0x1,-0x4(%rbp)
   21.84  21.84 │                                 25:   cmpl    $0x270f,-0x4(%rbp)
   11.03  11.03 │0.61     3          |A   |-   |      ↑ jle     11
                │                                       nop
                │                                       pop     %rbp
    0.00   0.00 │0.24    20          |AA  |B   |      ← ret

Originally-by: default avatarTinghao Zhang <tinghao.zhang@intel.com>
Reviewed-by: default avatarAndi Kleen <ak@linux.intel.com>
Signed-off-by: default avatarKan Liang <kan.liang@linux.intel.com>
Acked-by: default avatarNamhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: https://lore.kernel.org/r/20240813160208.2493643-8-kan.liang@linux.intel.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 20d6f555
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -927,11 +927,15 @@ int cmd_annotate(int argc, const char **argv)
		sort_order = "dso,symbol";

	/*
	 * Set SORT_MODE__BRANCH so that annotate display IPC/Cycle
	 * if branch info is in perf data in TUI mode.
	 * Set SORT_MODE__BRANCH so that annotate displays IPC/Cycle and
	 * branch counters, if the corresponding branch info is available
	 * in the perf data in the TUI mode.
	 */
	if ((use_browser == 1 || annotate.use_stdio2) && annotate.has_br_stack)
	if ((use_browser == 1 || annotate.use_stdio2) && annotate.has_br_stack) {
		sort__mode = SORT_MODE__BRANCH;
		if (annotate.session->evlist->nr_br_cntr > 0)
			annotate_opts.show_br_cntr = true;
	}

	if (setup_sorting(NULL) < 0)
		usage_with_options(annotate_usage, options);
+16 −2
Original line number Diff line number Diff line
@@ -156,6 +156,7 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)
	struct symbol *sym = ms->sym;
	struct annotation *notes = symbol__annotation(sym);
	u8 pcnt_width = annotation__pcnt_width(notes);
	u8 cntr_width = annotation__br_cntr_width();
	int width;
	int diff = 0;

@@ -205,13 +206,13 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)

	ui_browser__set_color(browser, HE_COLORSET_JUMP_ARROWS);
	__ui_browser__line_arrow(browser,
				 pcnt_width + 2 + notes->src->widths.addr + width,
				 pcnt_width + 2 + notes->src->widths.addr + width + cntr_width,
				 from, to);

	diff = is_fused(ab, cursor);
	if (diff > 0) {
		ui_browser__mark_fused(browser,
				       pcnt_width + 3 + notes->src->widths.addr + width,
				       pcnt_width + 3 + notes->src->widths.addr + width + cntr_width,
				       from - diff, diff, to > from);
	}
}
@@ -714,6 +715,7 @@ static int annotate_browser__run(struct annotate_browser *browser,
	struct annotation *notes = symbol__annotation(ms->sym);
	const char *help = "Press 'h' for help on key bindings";
	int delay_secs = hbt ? hbt->refresh : 0;
	char *br_cntr_text = NULL;
	char title[256];
	int key;

@@ -730,6 +732,8 @@ static int annotate_browser__run(struct annotate_browser *browser,

	nd = browser->curr_hot;

	annotation_br_cntr_abbr_list(&br_cntr_text, evsel, false);

	while (1) {
		key = ui_browser__run(&browser->b, delay_secs);

@@ -796,6 +800,7 @@ static int annotate_browser__run(struct annotate_browser *browser,
		"r             Run available scripts\n"
		"p             Toggle percent type [local/global]\n"
		"b             Toggle percent base [period/hits]\n"
		"B             Branch counter abbr list (Optional)\n"
		"?             Search string backwards\n"
		"f             Toggle showing offsets to full address\n");
			continue;
@@ -904,6 +909,14 @@ static int annotate_browser__run(struct annotate_browser *browser,
			hists__scnprintf_title(hists, title, sizeof(title));
			annotate_browser__show(&browser->b, title, help);
			continue;
		case 'B':
			if (br_cntr_text)
				ui_browser__help_window(&browser->b, br_cntr_text);
			else {
				ui_browser__help_window(&browser->b,
							"\n The branch counter is not available.\n");
			}
			continue;
		case 'f':
			annotation__toggle_full_addr(notes, ms);
			continue;
@@ -923,6 +936,7 @@ static int annotate_browser__run(struct annotate_browser *browser,
	}
out:
	ui_browser__hide(&browser->b);
	free(br_cntr_text);
	return key;
}

+2 −1
Original line number Diff line number Diff line
@@ -3705,7 +3705,8 @@ int block_hists_tui_browse(struct block_hist *bh, struct evsel *evsel,

	memset(&action, 0, sizeof(action));

	annotation_br_cntr_abbr_list(&br_cntr_text, evsel, false);
	if (!annotation_br_cntr_abbr_list(&br_cntr_text, evsel, false))
		annotate_opts.show_br_cntr = true;

	while (1) {
		key = hist_browser__run(browser, "? - help", true, 0);
+37 −3
Original line number Diff line number Diff line
@@ -501,8 +501,10 @@ static void annotation__count_and_fill(struct annotation *notes, u64 start, u64
	}
}

static int annotation__compute_ipc(struct annotation *notes, size_t size)
static int annotation__compute_ipc(struct annotation *notes, size_t size,
				   struct evsel *evsel)
{
	unsigned int br_cntr_nr = evsel->evlist->nr_br_cntr;
	int err = 0;
	s64 offset;

@@ -537,6 +539,20 @@ static int annotation__compute_ipc(struct annotation *notes, size_t size)
				al->cycles->max = ch->cycles_max;
				al->cycles->min = ch->cycles_min;
			}
			if (al && notes->branch->br_cntr) {
				if (!al->br_cntr) {
					al->br_cntr = calloc(br_cntr_nr, sizeof(u64));
					if (!al->br_cntr) {
						err = ENOMEM;
						break;
					}
				}
				al->num_aggr = ch->num_aggr;
				al->br_cntr_nr = br_cntr_nr;
				al->evsel = evsel;
				memcpy(al->br_cntr, &notes->branch->br_cntr[offset * br_cntr_nr],
				       br_cntr_nr * sizeof(u64));
			}
		}
	}

@@ -548,8 +564,10 @@ static int annotation__compute_ipc(struct annotation *notes, size_t size)
				struct annotation_line *al;

				al = annotated_source__get_line(notes->src, offset);
				if (al)
				if (al) {
					zfree(&al->cycles);
					zfree(&al->br_cntr);
				}
			}
		}
	}
@@ -1960,6 +1978,22 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati
					    "Cycle(min/max)");
		}

		if (annotate_opts.show_br_cntr) {
			if (show_title) {
				obj__printf(obj, "%*s ",
					    ANNOTATION__BR_CNTR_WIDTH,
					    "Branch Counter");
			} else {
				char *buf;

				if (!annotation_br_cntr_entry(&buf, al->br_cntr_nr, al->br_cntr,
							      al->num_aggr, al->evsel)) {
					obj__printf(obj, "%*s ", ANNOTATION__BR_CNTR_WIDTH, buf);
					free(buf);
				}
			}
		}

		if (show_title && !*al->line) {
			ipc_coverage_string(bf, sizeof(bf), notes);
			obj__printf(obj, "%*s", ANNOTATION__AVG_IPC_WIDTH, bf);
@@ -2056,7 +2090,7 @@ int symbol__annotate2(struct map_symbol *ms, struct evsel *evsel,
	annotation__set_index(notes);
	annotation__mark_jump_targets(notes, sym);

	err = annotation__compute_ipc(notes, size);
	err = annotation__compute_ipc(notes, size, evsel);
	if (err)
		return err;

+11 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ struct annotated_data_type;
#define ANNOTATION__CYCLES_WIDTH 6
#define ANNOTATION__MINMAX_CYCLES_WIDTH 19
#define ANNOTATION__AVG_IPC_WIDTH 36
#define ANNOTATION__BR_CNTR_WIDTH 30
#define ANNOTATION_DUMMY_LEN	256

struct annotation_options {
@@ -44,6 +45,7 @@ struct annotation_options {
	     show_nr_jumps,
	     show_minmax_cycle,
	     show_asm_raw,
	     show_br_cntr,
	     annotate_src,
	     full_addr;
	u8   offset_level;
@@ -104,6 +106,10 @@ struct annotation_line {
	char			*fileloc;
	char			*path;
	struct cycles_info	*cycles;
	int			 num_aggr;
	int			 br_cntr_nr;
	u64			*br_cntr;
	struct evsel		*evsel;
	int			 jump_sources;
	u32			 idx;
	int			 idx_asm;
@@ -353,6 +359,11 @@ static inline bool annotation_line__filter(struct annotation_line *al)
	return annotate_opts.hide_src_code && al->offset == -1;
}

static inline u8 annotation__br_cntr_width(void)
{
	return annotate_opts.show_br_cntr ? ANNOTATION__BR_CNTR_WIDTH : 0;
}

void annotation__update_column_widths(struct annotation *notes);
void annotation__toggle_full_addr(struct annotation *notes, struct map_symbol *ms);

Loading