[PATCH 1/1] perf tools: perf diff for different binaries
From: kan . liang
Date: Fri Oct 31 2014 - 15:52:38 EST
From: Kan Liang <kan.liang@xxxxxxxxx>
perf diff can display the differential profile between two perf.data
files. However, the perf.data files have to come from same binaries.
The patch introduced a key "symbol_name" for --sort option, so the user
can compare the perf.data files from different binaries, even different
kernel version. If symbol_name is set, perf diff display the
differential profile of functions.
It could help the user quickly locate the scaling regression caused by
new binaries/kernels.
Here is an example. I have two version of binaries. One is running on
kernel 3.16. The other is running on kernel 3.17.
Using perf record, I got two perf.data files, v1_1_6perf.data (version
one in 3.16) and v2_1_7perf.data (version two in 3.17).
If I run old perf diff with --sort dso,symbol, we cannot get any useful
information for the user space binary. Furthermore, it failed to compare
the kernel function. E.g. native_write_msr_safe.
perf diff -s dso,symbol --compute ratio v1_1_6perf.data v2_1_7perf.data
Event 'cycles'
Baseline Ratio Shared Object Symbol
........ .............. .................
....................................
[kernel.kallsyms] [k]
__update_entity_load_avg_contrib
[kernel.kallsyms] [k] _raw_spin_lock
[kernel.kallsyms] [k] apic_timer_interrupt
[kernel.kallsyms] [k] hrtimer_interrupt
0.01% [kernel.kallsyms] [k] native_write_msr_safe
[kernel.kallsyms] [k] native_write_msr_safe
0.01% [kernel.kallsyms] [k] notifier_call_chain
0.01% [kernel.kallsyms] [k] perf_event_task_tick
0.01% [kernel.kallsyms] [k] run_posix_cpu_timers
0.01% [kernel.kallsyms] [k] run_timer_softirq
0.01% [kernel.kallsyms] [k] trigger_load_balance
0.01% [kernel.kallsyms] [k] update_vsyscall
0.05% [unknown] [.] 0x0000000000400540
0.04% [unknown] [.] 0x0000000000400541
0.03% [unknown] [.] 0x000000000040054b
0.04% [unknown] [.] 0x0000000000400552
33.55% [unknown] [.] 0x0000000000400554
1.22% [unknown] [.] 0x000000000040055a
8.00% [unknown] [.] 0x000000000040055e
0.02% [unknown] [.] 0x0000000000400562
8.41% [unknown] [.] 0x0000000000400564
48.13% [unknown] [.] 0x000000000040056b
0.16% [unknown] [.] 0x0000000000400570
0.17% [unknown] [.] 0x0000000000400571
[unknown] [.] 0x0000000000400580
[unknown] [.] 0x0000000000400581
0.01% [unknown] [.] 0x0000000000400583
0.01% [unknown] [.] 0x0000000000400588
[unknown] [.] 0x000000000040058b
0.01% 1240.990221 [unknown] [.] 0x000000000040058d
[unknown] [.] 0x0000000000400590
0.06% [unknown] [.] 0x0000000000400591
[unknown] [.] 0x0000000000400593
0.04% [unknown] [.] 0x0000000000400595
0.01% 1240.603148 [unknown] [.] 0x0000000000400597
[unknown] [.] 0x000000000040059b
[unknown] [.] 0x000000000040059d
[unknown] [.] 0x00000000004005a1
[unknown] [.] 0x00000000004005a5
[unknown] [.] 0x00000000004005a7
[unknown] [.] 0x00000000004005a8
[unknown] [.] 0x00000000004005aa
[unknown] [.] 0x00000000004005ba
[unknown] [.] 0x00000000004005bf
[unknown] [.] 0x00000000004005c4
[unknown] [.] 0x00000000004005c9
[unknown] [.] 0x00000000004005ce
[unknown] [.] 0x00000000004005d2
[unknown] [.] 0x00000000004005d6
[unknown] [.] 0x00000000004005d8
[unknown] [.] 0x00000000004005f5
With the key "symbol_name", we can easily get the differential profile
from different binary versions and different kernel versions.
./perf diff -s dso,symbol_name --compute ratio v1_1_6perf.data v2_1_7perf.data
Event 'cycles'
Baseline Ratio Shared Object Symbol Name
........ .............. .................
....................................
[kernel.kallsyms] [k]
__update_entity_load_avg_contrib
[kernel.kallsyms] [k] _raw_spin_lock
[kernel.kallsyms] [k] apic_timer_interrupt
[kernel.kallsyms] [k] hrtimer_interrupt
0.01% 1.998522 [kernel.kallsyms] [k] native_write_msr_safe
0.01% [kernel.kallsyms] [k] notifier_call_chain
0.01% [kernel.kallsyms] [k] perf_event_task_tick
0.01% [kernel.kallsyms] [k] run_posix_cpu_timers
0.01% [kernel.kallsyms] [k] run_timer_softirq
0.01% [kernel.kallsyms] [k] trigger_load_balance
0.01% [kernel.kallsyms] [k] update_vsyscall
tchain_edit [.] f1
0.14% 3.913444 tchain_edit [.] f2
99.82% 1.005478 tchain_edit [.] f3
Signed-off-by: Kan Liang <kan.liang@xxxxxxxxx>
---
tools/perf/builtin-diff.c | 5 ++++-
tools/perf/util/sort.c | 26 ++++++++++++++++++++++++++
tools/perf/util/sort.h | 3 +++
3 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 25114c9..71183c1 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -743,7 +743,7 @@ static const struct option options[] = {
OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
"only consider these symbols"),
OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
- "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..."
+ "sort by key(s): pid, comm, dso, symbol, symbol_name, parent, cpu, srcline, ..."
" Please refer the man page for the complete list."),
OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator",
"separator for columns, no spaces will be added between "
@@ -1164,6 +1164,9 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
if (setup_sorting() < 0)
usage_with_options(diff_usage, options);
+ if (sort__has_sym_name)
+ tool.mmap2 = perf_event__process_mmap2;
+
setup_pager();
sort__setup_elide(NULL);
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 9402885..1226e37 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -20,6 +20,7 @@ int have_ignore_callees = 0;
int sort__need_collapse = 0;
int sort__has_parent = 0;
int sort__has_sym = 0;
+int sort__has_sym_name = 0;
int sort__has_dso = 0;
enum sort_mode sort__mode = SORT_MODE__NORMAL;
@@ -280,6 +281,27 @@ struct sort_entry sort_sym = {
.se_width_idx = HISTC_SYMBOL,
};
+static int64_t
+sort__sym_name_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+ const char *sym_name_l, *sym_name_r;
+
+ if (!left->ms.sym || !right->ms.sym)
+ return cmp_null(right->ms.sym, left->ms.sym);
+
+ sym_name_l = left->ms.sym->name;
+ sym_name_r = right->ms.sym->name;
+
+ return strcmp(sym_name_l, sym_name_r);
+}
+
+struct sort_entry sort_sym_name = {
+ .se_header = "Symbol Name",
+ .se_cmp = sort__sym_name_cmp,
+ .se_sort = sort__sym_sort,
+ .se_snprintf = hist_entry__sym_snprintf,
+ .se_width_idx = HISTC_SYMBOL,
+};
/* --sort srcline */
static int64_t
@@ -1170,6 +1192,7 @@ static struct sort_dimension common_sort_dimensions[] = {
DIM(SORT_COMM, "comm", sort_comm),
DIM(SORT_DSO, "dso", sort_dso),
DIM(SORT_SYM, "symbol", sort_sym),
+ DIM(SORT_SYM_NAME, "symbol_name", sort_sym_name),
DIM(SORT_PARENT, "parent", sort_parent),
DIM(SORT_CPU, "cpu", sort_cpu),
DIM(SORT_SRCLINE, "srcline", sort_srcline),
@@ -1430,6 +1453,8 @@ int sort_dimension__add(const char *tok)
sort__has_parent = 1;
} else if (sd->entry == &sort_sym) {
sort__has_sym = 1;
+ } else if (sd->entry == &sort_sym_name) {
+ sort__has_sym_name = 1;
} else if (sd->entry == &sort_dso) {
sort__has_dso = 1;
}
@@ -1809,6 +1834,7 @@ void reset_output_field(void)
sort__need_collapse = 0;
sort__has_parent = 0;
sort__has_sym = 0;
+ sort__has_sym_name = 0;
sort__has_dso = 0;
field_order = NULL;
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index c03e4ff..9b43c6c 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -34,10 +34,12 @@ extern int have_ignore_callees;
extern int sort__need_collapse;
extern int sort__has_parent;
extern int sort__has_sym;
+extern int sort__has_sym_name;
extern enum sort_mode sort__mode;
extern struct sort_entry sort_comm;
extern struct sort_entry sort_dso;
extern struct sort_entry sort_sym;
+extern struct sort_entry sort_sym_name;
extern struct sort_entry sort_parent;
extern struct sort_entry sort_dso_from;
extern struct sort_entry sort_dso_to;
@@ -161,6 +163,7 @@ enum sort_type {
SORT_COMM,
SORT_DSO,
SORT_SYM,
+ SORT_SYM_NAME,
SORT_PARENT,
SORT_CPU,
SORT_SRCLINE,
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/