Messages in this thread Patch in this message | | | From | Jin Yao <> | Subject | [PATCH v3 6/7] perf diff: Print the basic block cycles diff | Date | Mon, 17 Jun 2019 20:50:56 +0800 |
| |
perf record -b ./div perf record -b ./div
Following is the default perf diff output
# perf diff
# Event 'cycles' # # Baseline Delta Abs Shared Object Symbol # ........ ......... ................ .................................... # 49.03% +0.30% div [.] main 16.29% -0.20% libc-2.23.so [.] __random 18.82% -0.07% libc-2.23.so [.] __random_r 8.11% -0.04% div [.] compute_flag 2.25% +0.01% div [.] rand@plt 0.00% +0.01% [kernel.vmlinux] [k] task_tick_fair 5.46% +0.01% libc-2.23.so [.] rand 0.01% -0.01% [kernel.vmlinux] [k] native_irq_return_iret 0.00% -0.00% [kernel.vmlinux] [k] interrupt_entry
This patch creates a new computation selection 'cycles'.
# perf diff -c cycles
# Event 'cycles' # # Baseline Block cycles diff [start:end] Shared Object Symbol # ........ .................................... ................ .................................... # 49.03% -9 [ 4ef: 520] div [.] main 49.03% 0 [ 4e8: 4ea] div [.] main 49.03% 0 [ 4ef: 500] div [.] main 49.03% 0 [ 4ef: 51c] div [.] main 49.03% 0 [ 4ef: 535] div [.] main 18.82% 0 [ 3ac40: 3ac4d] libc-2.23.so [.] __random_r 18.82% 0 [ 3ac40: 3ac5c] libc-2.23.so [.] __random_r 18.82% 0 [ 3ac40: 3ac76] libc-2.23.so [.] __random_r 18.82% 0 [ 3ac40: 3ac88] libc-2.23.so [.] __random_r 18.82% 0 [ 3ac90: 3ac9c] libc-2.23.so [.] __random_r 16.29% -8 [ 3aac0: 3aac0] libc-2.23.so [.] __random 16.29% 0 [ 3aac0: 3aad2] libc-2.23.so [.] __random 16.29% 0 [ 3aae0: 3aae7] libc-2.23.so [.] __random 16.29% 0 [ 3ab03: 3ab0f] libc-2.23.so [.] __random 16.29% 0 [ 3ab14: 3ab1b] libc-2.23.so [.] __random 16.29% 0 [ 3ab28: 3ab2e] libc-2.23.so [.] __random 16.29% 0 [ 3ab4a: 3ab53] libc-2.23.so [.] __random 8.11% 0 [ 640: 644] div [.] compute_flag 8.11% 0 [ 649: 659] div [.] compute_flag 5.46% 0 [ 3af60: 3af60] libc-2.23.so [.] rand 5.46% 0 [ 3af60: 3af64] libc-2.23.so [.] rand 2.25% 0 [ 490: 490] div [.] rand@plt 0.01% 26 [ c00a27: c00a27] [kernel.vmlinux] [k] native_irq_return_iret 0.00% -157 [ 2bf9f2: 2bfa63] [kernel.vmlinux] [k] update_blocked_averages 0.00% -56 [ 2bf980: 2bf9d3] [kernel.vmlinux] [k] update_blocked_averages 0.00% 48 [ 2bf934: 2bf942] [kernel.vmlinux] [k] update_blocked_averages 0.00% 3 [ 2bfb38: 2bfb67] [kernel.vmlinux] [k] update_blocked_averages 0.00% 0 [ 2bf968: 2bf97b] [kernel.vmlinux] [k] update_blocked_averages
"[start:end]" indicates the basic block range. The output is sorted by "Baseline" and the basic blocks in the same function are sorted by cycles diff.
v3: --- Cast 'struct hist_entry' to 'struct block_hist' in hist_entry__block_fprintf. Use symbol_conf.report_block to check if executing hist_entry__block_fprintf.
v2: --- Keep standard perf diff format and display the 'Baseline' and 'Shared Object'.
Signed-off-by: Jin Yao <yao.jin@linux.intel.com> --- tools/perf/builtin-diff.c | 59 ++++++++++++++++++++++++++++++++++++++++--- tools/perf/ui/stdio/hist.c | 27 ++++++++++++++++++++ tools/perf/util/hist.c | 18 +++++++++++++ tools/perf/util/hist.h | 3 +++ tools/perf/util/symbol_conf.h | 1 + 5 files changed, 104 insertions(+), 4 deletions(-)
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 5f5a9a9..a56d941 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -46,6 +46,7 @@ enum { PERF_HPP_DIFF__WEIGHTED_DIFF, PERF_HPP_DIFF__FORMULA, PERF_HPP_DIFF__DELTA_ABS, + PERF_HPP_DIFF__CYCLES, PERF_HPP_DIFF__MAX_INDEX }; @@ -114,6 +115,7 @@ static int compute_2_hpp[COMPUTE_MAX] = { [COMPUTE_DELTA_ABS] = PERF_HPP_DIFF__DELTA_ABS, [COMPUTE_RATIO] = PERF_HPP_DIFF__RATIO, [COMPUTE_WEIGHTED_DIFF] = PERF_HPP_DIFF__WEIGHTED_DIFF, + [COMPUTE_CYCLES] = PERF_HPP_DIFF__CYCLES, }; #define MAX_COL_WIDTH 70 @@ -152,6 +154,10 @@ static struct header_column { [PERF_HPP_DIFF__FORMULA] = { .name = "Formula", .width = MAX_COL_WIDTH, + }, + [PERF_HPP_DIFF__CYCLES] = { + .name = "Block cycles diff [start:end]", + .width = 36, } }; @@ -239,8 +245,6 @@ static int setup_compute(const struct option *opt, const char *str, for (i = 0; i < COMPUTE_MAX; i++) if (!strcmp(cstr, compute_names[i])) { *cp = i; - if (i == COMPUTE_CYCLES) - break; return setup_compute_opt(option); } @@ -1002,6 +1006,9 @@ static void hists__process(struct hists *hists) hists__precompute(hists); hists__output_resort(hists, NULL); + if (compute == COMPUTE_CYCLES) + symbol_conf.report_block = true; + hists__fprintf(hists, !quiet, 0, 0, 0, stdout, !symbol_conf.use_callchain); } @@ -1257,7 +1264,7 @@ static const struct option options[] = { OPT_BOOLEAN('b', "baseline-only", &show_baseline_only, "Show only items with match in baseline"), OPT_CALLBACK('c', "compute", &compute, - "delta,delta-abs,ratio,wdiff:w1,w2 (default delta-abs)", + "delta,delta-abs,ratio,wdiff:w1,w2 (default delta-abs),cycles", "Entries differential computation selection", setup_compute), OPT_BOOLEAN('p', "period", &show_period, @@ -1335,6 +1342,29 @@ static int hpp__entry_baseline(struct hist_entry *he, char *buf, size_t size) return ret; } +static int cycles_printf(struct hist_entry *he, struct hist_entry *pair, + struct perf_hpp *hpp, int width) +{ + struct block_hist *bh = container_of(he, struct block_hist, he); + struct block_hist *bh_pair = container_of(pair, struct block_hist, he); + struct hist_entry *block_he; + struct block_info *bi; + char buf[128]; + + block_he = hists__get_entry(&bh_pair->block_hists, bh->block_idx); + if (!block_he) { + hpp->skip = true; + return 0; + } + + bi = block_he->block_info; + scnprintf(buf, sizeof(buf), "%ld [%12lx:%12lx]", + block_he->diff.cycles, bi->sym->start + bi->start, + bi->sym->start + bi->end); + + return scnprintf(hpp->buf, hpp->size, "%*s", width, buf); +} + static int __hpp__color_compare(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct hist_entry *he, int comparison_method) @@ -1346,8 +1376,17 @@ static int __hpp__color_compare(struct perf_hpp_fmt *fmt, s64 wdiff; char pfmt[20] = " "; - if (!pair) + if (!pair) { + if (comparison_method == COMPUTE_CYCLES) { + struct block_hist *bh; + + bh = container_of(he, struct block_hist, he); + if (bh->block_idx) + hpp->skip = true; + } + goto no_print; + } switch (comparison_method) { case COMPUTE_DELTA: @@ -1382,6 +1421,8 @@ static int __hpp__color_compare(struct perf_hpp_fmt *fmt, return color_snprintf(hpp->buf, hpp->size, get_percent_color(wdiff), pfmt, wdiff); + case COMPUTE_CYCLES: + return cycles_printf(he, pair, hpp, dfmt->header_width); default: BUG_ON(1); } @@ -1411,6 +1452,12 @@ static int hpp__color_wdiff(struct perf_hpp_fmt *fmt, return __hpp__color_compare(fmt, hpp, he, COMPUTE_WEIGHTED_DIFF); } +static int hpp__color_cycles(struct perf_hpp_fmt *fmt, + struct perf_hpp *hpp, struct hist_entry *he) +{ + return __hpp__color_compare(fmt, hpp, he, COMPUTE_CYCLES); +} + static void hpp__entry_unpair(struct hist_entry *he, int idx, char *buf, size_t size) { @@ -1612,6 +1659,10 @@ static void data__hpp_register(struct data__file *d, int idx) fmt->color = hpp__color_delta; fmt->sort = hist_entry__cmp_delta_abs; break; + case PERF_HPP_DIFF__CYCLES: + fmt->color = hpp__color_cycles; + fmt->sort = hist_entry__cmp_nop; + break; default: fmt->sort = hist_entry__cmp_nop; break; diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index a60f299..4e74bb7 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c @@ -531,6 +531,30 @@ static int hist_entry__hierarchy_fprintf(struct hist_entry *he, return printed; } +static int hist_entry__block_fprintf(struct hist_entry *he, + char *bf, size_t size, + FILE *fp) +{ + struct block_hist *bh = container_of(he, struct block_hist, he); + int ret = 0; + + for (unsigned int i = 0; i < bh->block_hists.nr_entries; i++) { + struct perf_hpp hpp = { + .buf = bf, + .size = size, + .skip = false, + }; + + bh->block_idx = i; + hist_entry__snprintf(he, &hpp); + + if (!hpp.skip) + ret += fprintf(fp, "%s\n", bf); + } + + return ret; +} + static int hist_entry__fprintf(struct hist_entry *he, size_t size, char *bf, size_t bfsz, FILE *fp, bool ignore_callchains) @@ -550,6 +574,9 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size, if (symbol_conf.report_hierarchy) return hist_entry__hierarchy_fprintf(he, &hpp, hists, fp); + if (symbol_conf.report_block) + return hist_entry__block_fprintf(he, bf, size, fp); + hist_entry__snprintf(he, &hpp); ret = fprintf(fp, "%s\n", bf); diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 680ad93..2fb9cb2 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -376,6 +376,24 @@ void hists__delete_entries(struct hists *hists) } } +struct hist_entry *hists__get_entry(struct hists *hists, int idx) +{ + struct rb_node *next = rb_first_cached(&hists->entries); + struct hist_entry *n; + int i = 0; + + while (next) { + n = rb_entry(next, struct hist_entry, rb_node); + if (i == idx) + return n; + + next = rb_next(&n->rb_node); + i++; + } + + return NULL; +} + /* * histogram, sorted on item, collects periods */ diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index c8f7d66..9124b54 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -184,6 +184,8 @@ void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel); void hists__delete_entries(struct hists *hists); void hists__output_recalc_col_len(struct hists *hists, int max_rows); +struct hist_entry *hists__get_entry(struct hists *hists, int idx); + u64 hists__total_period(struct hists *hists); void hists__reset_stats(struct hists *hists); void hists__inc_stats(struct hists *hists, struct hist_entry *h); @@ -249,6 +251,7 @@ struct perf_hpp { size_t size; const char *sep; void *ptr; + bool skip; }; struct perf_hpp_fmt { diff --git a/tools/perf/util/symbol_conf.h b/tools/perf/util/symbol_conf.h index 382ba63..be4b244 100644 --- a/tools/perf/util/symbol_conf.h +++ b/tools/perf/util/symbol_conf.h @@ -39,6 +39,7 @@ struct symbol_conf { hide_unresolved, raw_trace, report_hierarchy, + report_block, inline_name; const char *vmlinux_name, *kallsyms_name, -- 2.7.4
| |