Skip to content

Commit 0e332f0

Browse files
Andi Kleenacmel
authored andcommitted
perf tools: Add support for cycles, weight branch_info field
cycles is a new branch_info field available on some CPUs that indicates the time deltas between branches in the LBR. Add a sort key and output code for the cycles to allow to display the basic block cycles individually in perf report. We also pass in the cycles for weight when LBRs are processed, which allows to get global and local weight, to get an estimate of the total cost. And also print the cycles information for perf report -D. I also added printing for the previously missing LBR flags (mispredict etc.) Signed-off-by: Andi Kleen <[email protected]> Acked-by: 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 93df8a1 commit 0e332f0

File tree

7 files changed

+43
-6
lines changed

7 files changed

+43
-6
lines changed

tools/perf/Documentation/perf-report.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ OPTIONS
109109
- mispredict: "N" for predicted branch, "Y" for mispredicted branch
110110
- in_tx: branch in TSX transaction
111111
- abort: TSX transaction abort.
112+
- cycles: Cycles in basic block
112113

113114
And default sort keys are changed to comm, dso_from, symbol_from, dso_to
114115
and symbol_to, see '--branch-stack'.

tools/perf/util/event.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ struct branch_flags {
134134
u64 predicted:1;
135135
u64 in_tx:1;
136136
u64 abort:1;
137-
u64 reserved:60;
137+
u64 cycles:16;
138+
u64 reserved:44;
138139
};
139140

140141
struct branch_entry {

tools/perf/util/hist.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,8 @@ iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *a
618618
* and not events sampled. Thus we use a pseudo period of 1.
619619
*/
620620
he = __hists__add_entry(hists, al, iter->parent, &bi[i], NULL,
621-
1, 1, 0, true);
621+
1, bi->flags.cycles ? bi->flags.cycles : 1,
622+
0, true);
622623
if (he == NULL)
623624
return -ENOMEM;
624625

tools/perf/util/hist.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ enum hist_column {
4747
HISTC_MEM_SNOOP,
4848
HISTC_MEM_DCACHELINE,
4949
HISTC_TRANSACTION,
50+
HISTC_CYCLES,
5051
HISTC_NR_COLS, /* Last entry */
5152
};
5253

tools/perf/util/session.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -784,10 +784,18 @@ static void branch_stack__printf(struct perf_sample *sample)
784784

785785
printf("... branch stack: nr:%" PRIu64 "\n", sample->branch_stack->nr);
786786

787-
for (i = 0; i < sample->branch_stack->nr; i++)
788-
printf("..... %2"PRIu64": %016" PRIx64 " -> %016" PRIx64 "\n",
789-
i, sample->branch_stack->entries[i].from,
790-
sample->branch_stack->entries[i].to);
787+
for (i = 0; i < sample->branch_stack->nr; i++) {
788+
struct branch_entry *e = &sample->branch_stack->entries[i];
789+
790+
printf("..... %2"PRIu64": %016" PRIx64 " -> %016" PRIx64 " %hu cycles %s%s%s%s %x\n",
791+
i, e->from, e->to,
792+
e->flags.cycles,
793+
e->flags.mispred ? "M" : " ",
794+
e->flags.predicted ? "P" : " ",
795+
e->flags.abort ? "A" : " ",
796+
e->flags.in_tx ? "T" : " ",
797+
(unsigned)e->flags.reserved);
798+
}
791799
}
792800

793801
static void regs_dump__printf(u64 mask, u64 *regs)

tools/perf/util/sort.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,29 @@ static int hist_entry__mispredict_snprintf(struct hist_entry *he, char *bf,
526526
return repsep_snprintf(bf, size, "%-*.*s", width, width, out);
527527
}
528528

529+
static int64_t
530+
sort__cycles_cmp(struct hist_entry *left, struct hist_entry *right)
531+
{
532+
return left->branch_info->flags.cycles -
533+
right->branch_info->flags.cycles;
534+
}
535+
536+
static int hist_entry__cycles_snprintf(struct hist_entry *he, char *bf,
537+
size_t size, unsigned int width)
538+
{
539+
if (he->branch_info->flags.cycles == 0)
540+
return repsep_snprintf(bf, size, "%-*s", width, "-");
541+
return repsep_snprintf(bf, size, "%-*hd", width,
542+
he->branch_info->flags.cycles);
543+
}
544+
545+
struct sort_entry sort_cycles = {
546+
.se_header = "Basic Block Cycles",
547+
.se_cmp = sort__cycles_cmp,
548+
.se_snprintf = hist_entry__cycles_snprintf,
549+
.se_width_idx = HISTC_CYCLES,
550+
};
551+
529552
/* --sort daddr_sym */
530553
static int64_t
531554
sort__daddr_cmp(struct hist_entry *left, struct hist_entry *right)
@@ -1190,6 +1213,7 @@ static struct sort_dimension bstack_sort_dimensions[] = {
11901213
DIM(SORT_MISPREDICT, "mispredict", sort_mispredict),
11911214
DIM(SORT_IN_TX, "in_tx", sort_in_tx),
11921215
DIM(SORT_ABORT, "abort", sort_abort),
1216+
DIM(SORT_CYCLES, "cycles", sort_cycles),
11931217
};
11941218

11951219
#undef DIM

tools/perf/util/sort.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ enum sort_type {
185185
SORT_MISPREDICT,
186186
SORT_ABORT,
187187
SORT_IN_TX,
188+
SORT_CYCLES,
188189

189190
/* memory mode specific sort keys */
190191
__SORT_MEMORY_MODE,

0 commit comments

Comments
 (0)