Re: [PATCH] perf stat: Add Topdown metrics events as default events

From: Arnaldo Carvalho de Melo
Date: Wed Jan 27 2021 - 15:02:20 EST


Em Thu, Jan 21, 2021 at 05:37:52AM -0800, kan.liang@xxxxxxxxxxxxxxx escreveu:
> From: Kan Liang <kan.liang@xxxxxxxxxxxxxxx>
>
> The Topdown Microarchitecture Analysis (TMA) Method is a structured
> analysis methodology to identify critical performance bottlenecks in
> out-of-order processors. From the Ice Lake and later platforms, the
> Topdown information can be retrieved from the dedicated "metrics"
> register, which isn't impacted by other events. Also, the Topdown
> metrics support both per thread/process and per core measuring.
> Adding Topdown metrics events as default events can enrich the default
> measuring information, and would not cost any extra multiplexing.
>
> Introduce arch_evlist__add_default_attrs() to allow architecture
> specific default events. Add the Topdown metrics events in the X86
> specific arch_evlist__add_default_attrs(). Other architectures can
> add their own default events later separately.
>
> With the patch,

Thanks, applied.

- Arnaldo

> $perf stat sleep 1
>
> Performance counter stats for 'sleep 1':
>
> 0.82 msec task-clock:u # 0.001 CPUs utilized
> 0 context-switches:u # 0.000 K/sec
> 0 cpu-migrations:u # 0.000 K/sec
> 61 page-faults:u # 0.074 M/sec
> 319,941 cycles:u # 0.388 GHz
> 242,802 instructions:u # 0.76 insn per cycle
> 54,380 branches:u # 66.028 M/sec
> 4,043 branch-misses:u # 7.43% of all branches
> 1,585,555 slots:u # 1925.189 M/sec
> 238,941 topdown-retiring:u # 15.0% retiring
> 410,378 topdown-bad-spec:u # 25.8% bad speculation
> 634,222 topdown-fe-bound:u # 39.9% frontend bound
> 304,675 topdown-be-bound:u # 19.2% backend bound
>
> 1.001791625 seconds time elapsed
>
> 0.000000000 seconds user
> 0.001572000 seconds sys
>
> Signed-off-by: Kan Liang <kan.liang@xxxxxxxxxxxxxxx>
> ---
> tools/perf/arch/x86/util/Build | 1 +
> tools/perf/arch/x86/util/evlist.c | 15 +++++++++++++++
> tools/perf/builtin-stat.c | 3 +++
> tools/perf/util/evlist.c | 5 +++++
> tools/perf/util/evlist.h | 2 ++
> 5 files changed, 26 insertions(+)
> create mode 100644 tools/perf/arch/x86/util/evlist.c
>
> diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build
> index 347c39b960eb..ce1ec92fecdc 100644
> --- a/tools/perf/arch/x86/util/Build
> +++ b/tools/perf/arch/x86/util/Build
> @@ -6,6 +6,7 @@ perf-y += perf_regs.o
> perf-y += topdown.o
> perf-y += machine.o
> perf-y += event.o
> +perf-y += evlist.o
>
> perf-$(CONFIG_DWARF) += dwarf-regs.o
> perf-$(CONFIG_BPF_PROLOGUE) += dwarf-regs.o
> diff --git a/tools/perf/arch/x86/util/evlist.c b/tools/perf/arch/x86/util/evlist.c
> new file mode 100644
> index 000000000000..8c6732cc7794
> --- /dev/null
> +++ b/tools/perf/arch/x86/util/evlist.c
> @@ -0,0 +1,15 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <stdio.h>
> +#include "util/pmu.h"
> +#include "util/evlist.h"
> +#include "util/parse-events.h"
> +
> +#define TOPDOWN_L1_EVENTS "{slots,topdown-retiring,topdown-bad-spec,topdown-fe-bound,topdown-be-bound}"
> +
> +int arch_evlist__add_default_attrs(struct evlist *evlist)
> +{
> + if (!pmu_have_event("cpu", "slots"))
> + return 0;
> +
> + return parse_events(evlist, TOPDOWN_L1_EVENTS, NULL);
> +}
> diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> index 3c054b8d4677..abcdabaf1701 100644
> --- a/tools/perf/builtin-stat.c
> +++ b/tools/perf/builtin-stat.c
> @@ -1827,6 +1827,9 @@ static int add_default_attributes(void)
> }
> if (evlist__add_default_attrs(evsel_list, default_attrs1) < 0)
> return -1;
> +
> + if (arch_evlist__add_default_attrs(evsel_list) < 0)
> + return -1;
> }
>
> /* Detailed events get appended to the event list: */
> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> index 05363a7247c4..b38589d8c027 100644
> --- a/tools/perf/util/evlist.c
> +++ b/tools/perf/util/evlist.c
> @@ -303,6 +303,11 @@ int __evlist__add_default_attrs(struct evlist *evlist, struct perf_event_attr *a
> return evlist__add_attrs(evlist, attrs, nr_attrs);
> }
>
> +__weak int arch_evlist__add_default_attrs(struct evlist *evlist __maybe_unused)
> +{
> + return 0;
> +}
> +
> struct evsel *evlist__find_tracepoint_by_id(struct evlist *evlist, int id)
> {
> struct evsel *evsel;
> diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
> index 1aae75895dea..9eba4958a1e9 100644
> --- a/tools/perf/util/evlist.h
> +++ b/tools/perf/util/evlist.h
> @@ -110,6 +110,8 @@ int __evlist__add_default_attrs(struct evlist *evlist,
> #define evlist__add_default_attrs(evlist, array) \
> __evlist__add_default_attrs(evlist, array, ARRAY_SIZE(array))
>
> +int arch_evlist__add_default_attrs(struct evlist *evlist);
> +
> int evlist__add_dummy(struct evlist *evlist);
>
> int evlist__add_sb_event(struct evlist *evlist, struct perf_event_attr *attr,
> --
> 2.25.1
>

--

- Arnaldo