From: Namhyung Kim <namhyung@kernel.org>
To: Jiri Olsa <jolsa@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>,
lkml <linux-kernel@vger.kernel.org>,
Ingo Molnar <mingo@kernel.org>,
Peter Zijlstra <a.p.zijlstra@chello.nl>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
David Ahern <dsahern@gmail.com>, Andi Kleen <andi@firstfloor.org>,
kernel-team@lge.com
Subject: Re: [PATCH 4/4] perf stat: Use group read for event groups
Date: Sun, 23 Jul 2017 09:53:00 +0900 [thread overview]
Message-ID: <20170723005300.GA3396@danjae.aot.lge.com> (raw)
In-Reply-To: <20170721121212.21414-5-jolsa@kernel.org>
On Fri, Jul 21, 2017 at 02:12:12PM +0200, Jiri Olsa wrote:
> Make perf stat use group read if there are groups
> defined. The group read will get the values for all
> member of groups within a single syscall instead of
> calling read syscall for every event.
>
> We can see considerable less amount of kernel cycles
> spent on single group read, than reading each event
> separately, like for following perf stat command:
>
> # perf stat -e {cycles,instructions} -I 10 -a sleep 1
>
> Monitored with "perf stat -r 5 -e '{cycles:u,cycles:k}'"
>
> Before:
>
> 24,325,676 cycles:u
> 297,040,775 cycles:k
>
> 1.038554134 seconds time elapsed
>
> After:
> 25,034,418 cycles:u
> 158,256,395 cycles:k
>
> 1.036864497 seconds time elapsed
>
> The perf_evsel__open fallback changes contributed by Andi Kleen.
>
> Link: http://lkml.kernel.org/n/tip-b6g8qarwvptr81cqdtfst59u@git.kernel.org
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
> tools/perf/builtin-stat.c | 30 +++++++++++++++++++++++++++---
> tools/perf/util/counts.h | 1 +
> tools/perf/util/evsel.c | 10 ++++++++++
> 3 files changed, 38 insertions(+), 3 deletions(-)
>
> diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> index 48ac53b199fc..866da7aa54bf 100644
> --- a/tools/perf/builtin-stat.c
> +++ b/tools/perf/builtin-stat.c
> @@ -213,10 +213,20 @@ static void perf_stat__reset_stats(void)
> static int create_perf_stat_counter(struct perf_evsel *evsel)
> {
> struct perf_event_attr *attr = &evsel->attr;
> + struct perf_evsel *leader = evsel->leader;
>
> - if (stat_config.scale)
> + if (stat_config.scale) {
> attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
> PERF_FORMAT_TOTAL_TIME_RUNNING;
> + }
> +
> + /*
> + * The event is part of non trivial group, let's enable
> + * the group read (for leader) and ID retrieval for all
> + * members.
> + */
> + if (leader->nr_members > 1)
> + attr->read_format |= PERF_FORMAT_ID|PERF_FORMAT_GROUP;
I just wonder ID is really necessary. Doesn't it have same order we
can traverse with the for_each_group_member()?
Thanks,
Namhyung
>
> attr->inherit = !no_inherit;
>
> @@ -333,13 +343,21 @@ static int read_counter(struct perf_evsel *counter)
> struct perf_counts_values *count;
>
> count = perf_counts(counter->counts, cpu, thread);
> - if (perf_evsel__read(counter, cpu, thread, count)) {
> +
> + /*
> + * The leader's group read loads data into its group members
> + * (via perf_evsel__read_counter) and sets threir count->loaded.
> + */
> + if (!count->loaded &&
> + perf_evsel__read_counter(counter, cpu, thread)) {
> counter->counts->scaled = -1;
> perf_counts(counter->counts, cpu, thread)->ena = 0;
> perf_counts(counter->counts, cpu, thread)->run = 0;
> return -1;
> }
>
> + count->loaded = false;
> +
> if (STAT_RECORD) {
> if (perf_evsel__write_stat_event(counter, cpu, thread, count)) {
> pr_err("failed to write stat event\n");
> @@ -559,6 +577,11 @@ static int store_counter_ids(struct perf_evsel *counter)
> return __store_counter_ids(counter, cpus, threads);
> }
>
> +static bool perf_evsel__should_store_id(struct perf_evsel *counter)
> +{
> + return STAT_RECORD || counter->attr.read_format & PERF_FORMAT_ID;
> +}
> +
> static int __run_perf_stat(int argc, const char **argv)
> {
> int interval = stat_config.interval;
> @@ -631,7 +654,8 @@ static int __run_perf_stat(int argc, const char **argv)
> if (l > unit_width)
> unit_width = l;
>
> - if (STAT_RECORD && store_counter_ids(counter))
> + if (perf_evsel__should_store_id(counter) &&
> + store_counter_ids(counter))
> return -1;
> }
>
> diff --git a/tools/perf/util/counts.h b/tools/perf/util/counts.h
> index 34d8baaf558a..cb45a6aecf9d 100644
> --- a/tools/perf/util/counts.h
> +++ b/tools/perf/util/counts.h
> @@ -12,6 +12,7 @@ struct perf_counts_values {
> };
> u64 values[3];
> };
> + bool loaded;
> };
>
> struct perf_counts {
> diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> index 89aecf3a35c7..3735c9e0080d 100644
> --- a/tools/perf/util/evsel.c
> +++ b/tools/perf/util/evsel.c
> @@ -49,6 +49,7 @@ static struct {
> bool clockid_wrong;
> bool lbr_flags;
> bool write_backward;
> + bool group_read;
> } perf_missing_features;
>
> static clockid_t clockid;
> @@ -1321,6 +1322,7 @@ perf_evsel__set_count(struct perf_evsel *counter, int cpu, int thread,
> count->val = val;
> count->ena = ena;
> count->run = run;
> + count->loaded = true;
> }
>
> static int
> @@ -1677,6 +1679,8 @@ int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
> if (perf_missing_features.lbr_flags)
> evsel->attr.branch_sample_type &= ~(PERF_SAMPLE_BRANCH_NO_FLAGS |
> PERF_SAMPLE_BRANCH_NO_CYCLES);
> + if (perf_missing_features.group_read && evsel->attr.inherit)
> + evsel->attr.read_format &= ~(PERF_FORMAT_GROUP|PERF_FORMAT_ID);
> retry_sample_id:
> if (perf_missing_features.sample_id_all)
> evsel->attr.sample_id_all = 0;
> @@ -1832,6 +1836,12 @@ int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
> perf_missing_features.lbr_flags = true;
> pr_debug2("switching off branch sample type no (cycles/flags)\n");
> goto fallback_missing_features;
> + } else if (!perf_missing_features.group_read &&
> + evsel->attr.inherit &&
> + (evsel->attr.read_format & PERF_FORMAT_GROUP)) {
> + perf_missing_features.group_read = true;
> + pr_debug2("switching off group read\n");
> + goto fallback_missing_features;
> }
> out_close:
> do {
> --
> 2.9.4
>
next prev parent reply other threads:[~2017-07-23 0:54 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-21 12:12 [PATCH 0/4] perf stat: Enable group read of counters Jiri Olsa
2017-07-21 12:12 ` [PATCH 1/4] perf tools: Add verbose output for sys_perf_event_open fallback Jiri Olsa
2017-07-26 17:23 ` [tip:perf/core] perf evsel: " tip-bot for Jiri Olsa
2017-07-21 12:12 ` [PATCH 2/4] perf tools: Add perf_evsel__read_size function Jiri Olsa
2017-07-21 12:12 ` [PATCH 3/4] perf tools: Add perf_evsel__read_counter function Jiri Olsa
2017-07-26 1:41 ` Arnaldo Carvalho de Melo
2017-07-26 1:42 ` Arnaldo Carvalho de Melo
2017-07-26 7:30 ` Jiri Olsa
2017-07-21 12:12 ` [PATCH 4/4] perf stat: Use group read for event groups Jiri Olsa
2017-07-23 0:53 ` Namhyung Kim [this message]
2017-07-24 7:31 ` Jiri Olsa
2017-07-21 17:07 ` [PATCH 0/4] perf stat: Enable group read of counters Arnaldo Carvalho de Melo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170723005300.GA3396@danjae.aot.lge.com \
--to=namhyung@kernel.org \
--cc=a.p.zijlstra@chello.nl \
--cc=acme@kernel.org \
--cc=alexander.shishkin@linux.intel.com \
--cc=andi@firstfloor.org \
--cc=dsahern@gmail.com \
--cc=jolsa@kernel.org \
--cc=kernel-team@lge.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®