Commit ace4f8fa authored by Jin Yao's avatar Jin Yao Committed by Arnaldo Carvalho de Melo

perf annotate: Compute average IPC and IPC coverage per symbol

Add support to 'perf report' annotate view or 'perf annotate --stdio2'
to aggregate the IPC derived from timed LBRs per symbol. We compute the
average IPC and the IPC coverage percentage.

For example:

  $ perf annotate --stdio2

  Percent  IPC Cycle (Average IPC: 2.30, IPC Coverage: 54.8%)

                          Disassembly of section .text:

                          000000000003aac0 <random@@GLIBC_2.2.5>:
    8.32  3.28              sub    $0x18,%rsp
          3.28              mov    $0x1,%esi
          3.28              xor    %eax,%eax
          3.28              cmpl   $0x0,argp_program_version_hook@@GLIBC_2.2.5+0x1e0
   11.57  3.28     1      ↓ je     20
                            lock   cmpxchg %esi,__abort_msg@@GLIBC_PRIVATE+0x8a0
                          ↓ jne    29
                          ↓ jmp    43
   11.57  1.10        20:   cmpxchg %esi,__abort_msg@@GLIBC_PRIVATE+0x8a0
    0.00  1.10     1      ↓ je     43
                      29:   lea    __abort_msg@@GLIBC_PRIVATE+0x8a0,%rdi
                            sub    $0x80,%rsp
                          → callq  __lll_lock_wait_private
                            add    $0x80,%rsp
    0.00  3.00        43:   lea    __ctype_b@GLIBC_2.2.5+0x38,%rdi
          3.00              lea    0xc(%rsp),%rsi
    8.49  3.00     1      → callq  __random_r
    7.91  1.94              cmpl   $0x0,argp_program_version_hook@@GLIBC_2.2.5+0x1e0
    0.00  1.94     1      ↓ je     68
                            lock   decl   __abort_msg@@GLIBC_PRIVATE+0x8a0
                          ↓ jne    70
                          ↓ jmp    8a
    0.00  2.00        68:   decl   __abort_msg@@GLIBC_PRIVATE+0x8a0
   21.56  2.00     1      ↓ je     8a
                      70:   lea    __abort_msg@@GLIBC_PRIVATE+0x8a0,%rdi
                            sub    $0x80,%rsp
                          → callq  __lll_unlock_wake_private
                            add    $0x80,%rsp
   21.56  2.90        8a:   movslq 0xc(%rsp),%rax
          2.90              add    $0x18,%rsp
    9.03  2.90     1      ← retq

It shows for this symbol the average IPC is 2.30 and the IPC coverage is
54.8%.
Signed-off-by: default avatarJin Yao <yao.jin@linux.intel.com>
Reviewed-by: default avatarIngo Molnar <mingo@kernel.org>
Reviewed-by: default avatarJiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1543586097-27632-2-git-send-email-yao.jin@linux.intel.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 44e92f83
...@@ -1000,6 +1000,7 @@ static unsigned annotation__count_insn(struct annotation *notes, u64 start, u64 ...@@ -1000,6 +1000,7 @@ static unsigned annotation__count_insn(struct annotation *notes, u64 start, u64
static void annotation__count_and_fill(struct annotation *notes, u64 start, u64 end, struct cyc_hist *ch) static void annotation__count_and_fill(struct annotation *notes, u64 start, u64 end, struct cyc_hist *ch)
{ {
unsigned n_insn; unsigned n_insn;
unsigned int cover_insn = 0;
u64 offset; u64 offset;
n_insn = annotation__count_insn(notes, start, end); n_insn = annotation__count_insn(notes, start, end);
...@@ -1013,21 +1014,34 @@ static void annotation__count_and_fill(struct annotation *notes, u64 start, u64 ...@@ -1013,21 +1014,34 @@ static void annotation__count_and_fill(struct annotation *notes, u64 start, u64
for (offset = start; offset <= end; offset++) { for (offset = start; offset <= end; offset++) {
struct annotation_line *al = notes->offsets[offset]; struct annotation_line *al = notes->offsets[offset];
if (al) if (al && al->ipc == 0.0) {
al->ipc = ipc; al->ipc = ipc;
cover_insn++;
}
}
if (cover_insn) {
notes->hit_cycles += ch->cycles;
notes->hit_insn += n_insn * ch->num;
notes->cover_insn += cover_insn;
} }
} }
} }
void annotation__compute_ipc(struct annotation *notes, size_t size) void annotation__compute_ipc(struct annotation *notes, size_t size)
{ {
u64 offset; s64 offset;
if (!notes->src || !notes->src->cycles_hist) if (!notes->src || !notes->src->cycles_hist)
return; return;
notes->total_insn = annotation__count_insn(notes, 0, size - 1);
notes->hit_cycles = 0;
notes->hit_insn = 0;
notes->cover_insn = 0;
pthread_mutex_lock(&notes->lock); pthread_mutex_lock(&notes->lock);
for (offset = 0; offset < size; ++offset) { for (offset = size - 1; offset >= 0; --offset) {
struct cyc_hist *ch; struct cyc_hist *ch;
ch = &notes->src->cycles_hist[offset]; ch = &notes->src->cycles_hist[offset];
...@@ -2563,6 +2577,22 @@ static void disasm_line__write(struct disasm_line *dl, struct annotation *notes, ...@@ -2563,6 +2577,22 @@ static void disasm_line__write(struct disasm_line *dl, struct annotation *notes,
disasm_line__scnprintf(dl, bf, size, !notes->options->use_offset); disasm_line__scnprintf(dl, bf, size, !notes->options->use_offset);
} }
static void ipc_coverage_string(char *bf, int size, struct annotation *notes)
{
double ipc = 0.0, coverage = 0.0;
if (notes->hit_cycles)
ipc = notes->hit_insn / ((double)notes->hit_cycles);
if (notes->total_insn) {
coverage = notes->cover_insn * 100.0 /
((double)notes->total_insn);
}
scnprintf(bf, size, "(Average IPC: %.2f, IPC Coverage: %.1f%%)",
ipc, coverage);
}
static void __annotation_line__write(struct annotation_line *al, struct annotation *notes, static void __annotation_line__write(struct annotation_line *al, struct annotation *notes,
bool first_line, bool current_entry, bool change_color, int width, bool first_line, bool current_entry, bool change_color, int width,
void *obj, unsigned int percent_type, void *obj, unsigned int percent_type,
...@@ -2658,6 +2688,11 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati ...@@ -2658,6 +2688,11 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati
ANNOTATION__MINMAX_CYCLES_WIDTH - 1, ANNOTATION__MINMAX_CYCLES_WIDTH - 1,
"Cycle(min/max)"); "Cycle(min/max)");
} }
if (show_title && !*al->line) {
ipc_coverage_string(bf, sizeof(bf), notes);
obj__printf(obj, "%*s", ANNOTATION__AVG_IPC_WIDTH, bf);
}
} }
obj__printf(obj, " "); obj__printf(obj, " ");
......
...@@ -64,6 +64,7 @@ bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2); ...@@ -64,6 +64,7 @@ bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2);
#define ANNOTATION__IPC_WIDTH 6 #define ANNOTATION__IPC_WIDTH 6
#define ANNOTATION__CYCLES_WIDTH 6 #define ANNOTATION__CYCLES_WIDTH 6
#define ANNOTATION__MINMAX_CYCLES_WIDTH 19 #define ANNOTATION__MINMAX_CYCLES_WIDTH 19
#define ANNOTATION__AVG_IPC_WIDTH 36
struct annotation_options { struct annotation_options {
bool hide_src_code, bool hide_src_code,
...@@ -262,6 +263,10 @@ struct annotation { ...@@ -262,6 +263,10 @@ struct annotation {
pthread_mutex_t lock; pthread_mutex_t lock;
u64 max_coverage; u64 max_coverage;
u64 start; u64 start;
u64 hit_cycles;
u64 hit_insn;
unsigned int total_insn;
unsigned int cover_insn;
struct annotation_options *options; struct annotation_options *options;
struct annotation_line **offsets; struct annotation_line **offsets;
int nr_events; int nr_events;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment