Messages in this thread Patch in this message | | | From | Jin Yao <> | Subject | [PATCH v2 11/14] perf diff: support hot blocks comparison | Date | Fri, 13 Mar 2020 15:11:15 +0800 |
| |
This patch reports the results of hot blocks comparison.
For example, following outputs are added to the end of hot streams reports.
# Output based on old stream (perf.data.old): # # Sampled Cycles% Avg Cycles New Stream Diff(cycles%,cycles) New Stream Sampled Cycles% New Stream Avg Cycles # ............... .......... ............................... .......................... ..................... # 24.76% 17 -4.54%, -7 - - 14.72% 7 0.13%, -1 - - 5.28% 2 [block not in new stream] - - 5.09% 2 0.52%, 0 - - 5.05% 2 -0.15%, -1 - - 4.18% 1 0.12%, 0 - - 3.16% 1 0.28%, 0 - -
If we enable the source line comparison, the output might be different.
# Output based on old stream (perf.data.old): # # Sampled Cycles% Avg Cycles New Stream Diff(cycles%,cycles) New Stream Sampled Cycles% New Stream Avg Cycles # ............... .......... ............................... .......................... ..................... # 24.76% 17 [block changed in new stream] 20.22% 10 14.72% 7 0.13%, -1 - - 5.28% 2 [block not in new stream] - - 5.09% 2 0.52%, 0 - - 5.05% 2 -0.15%, -1 - - 4.18% 1 [block changed in new stream] 4.31% 1 3.16% 1 0.28%, 0 - -
Signed-off-by: Jin Yao <yao.jin@linux.intel.com> --- tools/perf/builtin-diff.c | 85 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-)
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index dcbc9bba4e61..566e811054b1 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -49,6 +49,8 @@ struct perf_diff { bool src_cmp; bool stream; struct srclist *src_list; + u64 total_cycles; + float min_percent; }; /* Diff command specific HPP columns. */ @@ -76,8 +78,10 @@ struct diff_hpp_fmt { struct data__file { struct perf_session *session; + struct block_report *block_reports; struct perf_data data; int idx; + int nr_block_reports; struct hists *hists; struct callchain_streams *evsel_streams; int nr_evsel_streams; @@ -445,8 +449,10 @@ static int diff__process_sample_event(struct perf_tool *tool, pr_debug("problem adding hist entry, skipping event\n"); goto out_put; } - break; + hist__account_cycles(sample->branch_stack, &al, sample, false, + &pdiff->total_cycles); + break; default: if (!hists__add_entry(hists, &al, NULL, NULL, NULL, sample, true)) { @@ -992,6 +998,7 @@ static int process_base_stream(struct data__file *data_base, struct evlist *evlist_pair = data_pair->session->evlist; struct evsel *evsel_base, *evsel_pair; struct callchain_streams *es_base, *es_pair; + struct block_report *rep_base, *rep_pair; evlist__for_each_entry(evlist_base, evsel_base) { evsel_pair = evsel_match(evsel_base, evlist_pair); @@ -1014,6 +1021,37 @@ static int process_base_stream(struct data__file *data_base, callchain_stream_report(es_base, es_pair); } + evlist__for_each_entry(evlist_base, evsel_base) { + rep_base = block_info__get_report(data_base->block_reports, + data_base->nr_block_reports, + evsel_base->idx); + + if (!rep_base) + return -1; + + block_hists_addr2line(&rep_base->hist.block_hists, base_dir); + + evlist_pair = data_pair->session->evlist; + evsel_pair = evsel_match(evsel_base, evlist_pair); + if (!evsel_pair) + continue; + + rep_pair = block_info__get_report(data_pair->block_reports, + data_pair->nr_block_reports, + evsel_pair->idx); + + block_hists_addr2line(&rep_pair->hist.block_hists, pair_dir); + + block_info__match_report(rep_base, rep_pair, + pdiff.src_list, NULL); + + fprintf(stdout, "%s", title); + + use_browser = 0; + report__browse_block_hists(&rep_base->hist, pdiff.min_percent, + evsel_base, NULL, NULL); + } + return 0; } @@ -1142,6 +1180,26 @@ static int check_file_brstack(void) return 0; } +static struct block_report *create_block_reports(struct evlist *evlist, + u64 total_cycles, + int *nr_block_reports) +{ + struct block_report *reps; + int block_hpps[7] = { + PERF_HPP_REPORT__BLOCK_TOTAL_CYCLES_PCT, + PERF_HPP_REPORT__BLOCK_AVG_CYCLES, + PERF_HPP__BLOCK_NEW_STREAM_DIFF, + PERF_HPP__BLOCK_NEW_STREAM_TOTAL_CYCLES_PCT, + PERF_HPP__BLOCK_NEW_STREAM_AVG_CYCLES, + PERF_HPP_REPORT__BLOCK_RANGE, + PERF_HPP_REPORT__BLOCK_DSO, + }; + + reps = block_info__create_report(evlist, total_cycles, block_hpps, 7, + nr_block_reports); + return reps; +} + static struct callchain_streams *create_evsel_streams(struct evlist *evlist, int nr_streams_max, int *nr_evsel_streams) @@ -1197,6 +1255,8 @@ static int __cmd_diff(void) goto out_delete; } + pdiff.total_cycles = 0; + ret = perf_session__process_events(d->session); if (ret) { pr_err("Failed to process %s\n", d->data.path); @@ -1215,6 +1275,12 @@ static int __cmd_diff(void) &d->nr_evsel_streams); if (!d->evsel_streams) goto out_delete; + + d->block_reports = create_block_reports(d->session->evlist, + pdiff.total_cycles, + &d->nr_block_reports); + if (!d->block_reports) + goto out_delete; } } @@ -1225,6 +1291,11 @@ static int __cmd_diff(void) out_delete: data__for_each_file(i, d) { + if (d->block_reports) { + block_info__free_report(d->block_reports, + d->nr_block_reports); + } + perf_session__delete(d->session); data__free(d); } @@ -1244,6 +1315,15 @@ static int __cmd_diff(void) return ret; } +static int parse_percent_limit(const struct option *opt, const char *arg, + int unset __maybe_unused) +{ + struct perf_diff *d = opt->value; + + d->min_percent = strtof(arg, NULL); + return 0; +} + static const char * const diff_usage[] = { "perf diff [<options>] [old_file] [new_file]", NULL, @@ -1307,6 +1387,9 @@ static const struct option options[] = { OPT_STRING(0, "after", &pdiff.after_dir, "dir", "Source code directory corresponding to perf.data. " "WARNING: use with --before and --stream"), + OPT_CALLBACK(0, "percent-limit", &pdiff, "percent", + "Don't show entries under that percent", + parse_percent_limit), OPT_END() }; -- 2.17.1
| |