[v4,15/25] perf stat: Filter out unmatched aggregation for hybrid event
diff mbox series

Message ID 20210416140517.18206-16-yao.jin@linux.intel.com
State New
Headers show
Series
  • perf tool: AlderLake hybrid support series 1
Related show

Commit Message

Jin, Yao April 16, 2021, 2:05 p.m. UTC
perf-stat has supported some aggregation modes, such as --per-core,
--per-socket and etc. While for hybrid event, it may only available
on part of cpus. So for --per-core, we need to filter out the
unavailable cores, for --per-socket, filter out the unavailable
sockets, and so on.

Before:

  # perf stat --per-core -e cpu_core/cycles/ -a -- sleep 1

   Performance counter stats for 'system wide':

  S0-D0-C0           2            479,530      cpu_core/cycles/
  S0-D0-C4           2            175,007      cpu_core/cycles/
  S0-D0-C8           2            166,240      cpu_core/cycles/
  S0-D0-C12          2            704,673      cpu_core/cycles/
  S0-D0-C16          2            865,835      cpu_core/cycles/
  S0-D0-C20          2          2,958,461      cpu_core/cycles/
  S0-D0-C24          2            163,988      cpu_core/cycles/
  S0-D0-C28          2            164,729      cpu_core/cycles/
  S0-D0-C32          0      <not counted>      cpu_core/cycles/
  S0-D0-C33          0      <not counted>      cpu_core/cycles/
  S0-D0-C34          0      <not counted>      cpu_core/cycles/
  S0-D0-C35          0      <not counted>      cpu_core/cycles/
  S0-D0-C36          0      <not counted>      cpu_core/cycles/
  S0-D0-C37          0      <not counted>      cpu_core/cycles/
  S0-D0-C38          0      <not counted>      cpu_core/cycles/
  S0-D0-C39          0      <not counted>      cpu_core/cycles/

         1.003597211 seconds time elapsed

After:

  # perf stat --per-core -e cpu_core/cycles/ -a -- sleep 1

   Performance counter stats for 'system wide':

  S0-D0-C0           2            210,428      cpu_core/cycles/
  S0-D0-C4           2            444,830      cpu_core/cycles/
  S0-D0-C8           2            435,241      cpu_core/cycles/
  S0-D0-C12          2            423,976      cpu_core/cycles/
  S0-D0-C16          2            859,350      cpu_core/cycles/
  S0-D0-C20          2          1,559,589      cpu_core/cycles/
  S0-D0-C24          2            163,924      cpu_core/cycles/
  S0-D0-C28          2            376,610      cpu_core/cycles/

         1.003621290 seconds time elapsed

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v4:
 - No change.

 tools/perf/util/stat-display.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Comments

Jiri Olsa April 21, 2021, 6:29 p.m. UTC | #1
On Fri, Apr 16, 2021 at 10:05:07PM +0800, Jin Yao wrote:

SNIP

> diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
> index 5255d78b1c30..15eafd249e46 100644
> --- a/tools/perf/util/stat-display.c
> +++ b/tools/perf/util/stat-display.c
> @@ -643,6 +643,20 @@ static void aggr_cb(struct perf_stat_config *config,
>  	}
>  }
>  
> +static bool aggr_id_hybrid_matched(struct perf_stat_config *config,
> +				   struct evsel *counter, struct aggr_cpu_id id)
> +{
> +	struct aggr_cpu_id s;
> +
> +	for (int i = 0; i < evsel__nr_cpus(counter); i++) {
> +		s = config->aggr_get_id(config, evsel__cpus(counter), i);
> +		if (cpu_map__compare_aggr_cpu_id(s, id))
> +			return true;
> +	}
> +
> +	return false;
> +}
> +
>  static void print_counter_aggrdata(struct perf_stat_config *config,
>  				   struct evsel *counter, int s,
>  				   char *prefix, bool metric_only,
> @@ -656,6 +670,12 @@ static void print_counter_aggrdata(struct perf_stat_config *config,
>  	double uval;
>  
>  	ad.id = id = config->aggr_map->map[s];
> +
> +	if (perf_pmu__has_hybrid() &&
> +	    !aggr_id_hybrid_matched(config, counter, id)) {
> +		return;
> +	}
> +
>  	ad.val = ad.ena = ad.run = 0;
>  	ad.nr = 0;
>  	if (!collect_data(config, counter, aggr_cb, &ad))

there's same check in aggr_cb, so it seems like we could just make check in here:

	if (perf_pmu__has_hybrid() && ad.ena == 0)
		return;

without another extra loop

jirka
Jin, Yao April 22, 2021, 3:10 a.m. UTC | #2
Hi Jiri,

On 4/22/2021 2:29 AM, Jiri Olsa wrote:
> On Fri, Apr 16, 2021 at 10:05:07PM +0800, Jin Yao wrote:
> 
> SNIP
> 
>> diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
>> index 5255d78b1c30..15eafd249e46 100644
>> --- a/tools/perf/util/stat-display.c
>> +++ b/tools/perf/util/stat-display.c
>> @@ -643,6 +643,20 @@ static void aggr_cb(struct perf_stat_config *config,
>>   	}
>>   }
>>   
>> +static bool aggr_id_hybrid_matched(struct perf_stat_config *config,
>> +				   struct evsel *counter, struct aggr_cpu_id id)
>> +{
>> +	struct aggr_cpu_id s;
>> +
>> +	for (int i = 0; i < evsel__nr_cpus(counter); i++) {
>> +		s = config->aggr_get_id(config, evsel__cpus(counter), i);
>> +		if (cpu_map__compare_aggr_cpu_id(s, id))
>> +			return true;
>> +	}
>> +
>> +	return false;
>> +}
>> +
>>   static void print_counter_aggrdata(struct perf_stat_config *config,
>>   				   struct evsel *counter, int s,
>>   				   char *prefix, bool metric_only,
>> @@ -656,6 +670,12 @@ static void print_counter_aggrdata(struct perf_stat_config *config,
>>   	double uval;
>>   
>>   	ad.id = id = config->aggr_map->map[s];
>> +
>> +	if (perf_pmu__has_hybrid() &&
>> +	    !aggr_id_hybrid_matched(config, counter, id)) {
>> +		return;
>> +	}
>> +
>>   	ad.val = ad.ena = ad.run = 0;
>>   	ad.nr = 0;
>>   	if (!collect_data(config, counter, aggr_cb, &ad))
> 
> there's same check in aggr_cb, so it seems like we could just make check in here:
> 
> 	if (perf_pmu__has_hybrid() && ad.ena == 0)
> 		return;
> 
> without another extra loop
> 
> jirka
> 

I guess you recommended the patch like this:

  static void print_counter_aggrdata(struct perf_stat_config *config,
                                    struct evsel *counter, int s,
                                    char *prefix, bool metric_only,
@@ -670,17 +656,14 @@ static void print_counter_aggrdata(struct perf_stat_config *config,
         double uval;

         ad.id = id = config->aggr_map->map[s];
         ad.val = ad.ena = ad.run = 0;
         ad.nr = 0;
         if (!collect_data(config, counter, aggr_cb, &ad))
                 return;

+       if (perf_pmu__has_hybrid() && ad.ena == 0)
+               return;
+
         nr = ad.nr;
         ena = ad.ena;
         run = ad.run;

Yes, it works. The test log is,

# perf stat --per-core -e cpu_core/cycles/ -a -- sleep 1

  Performance counter stats for 'system wide':

S0-D0-C0           2          2,341,923      cpu_core/cycles/
S0-D0-C4           2          1,707,933      cpu_core/cycles/
S0-D0-C8           2            845,805      cpu_core/cycles/
S0-D0-C12          2          1,001,961      cpu_core/cycles/
S0-D0-C16          2            932,004      cpu_core/cycles/
S0-D0-C20          2          1,778,603      cpu_core/cycles/
S0-D0-C24          2            804,448      cpu_core/cycles/
S0-D0-C28          2            178,360      cpu_core/cycles/

        1.002264168 seconds time elapsed

Thanks
Jin Yao
Jiri Olsa April 22, 2021, 10:26 a.m. UTC | #3
On Thu, Apr 22, 2021 at 11:10:54AM +0800, Jin, Yao wrote:
> Hi Jiri,
> 
> On 4/22/2021 2:29 AM, Jiri Olsa wrote:
> > On Fri, Apr 16, 2021 at 10:05:07PM +0800, Jin Yao wrote:
> > 
> > SNIP
> > 
> > > diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
> > > index 5255d78b1c30..15eafd249e46 100644
> > > --- a/tools/perf/util/stat-display.c
> > > +++ b/tools/perf/util/stat-display.c
> > > @@ -643,6 +643,20 @@ static void aggr_cb(struct perf_stat_config *config,
> > >   	}
> > >   }
> > > +static bool aggr_id_hybrid_matched(struct perf_stat_config *config,
> > > +				   struct evsel *counter, struct aggr_cpu_id id)
> > > +{
> > > +	struct aggr_cpu_id s;
> > > +
> > > +	for (int i = 0; i < evsel__nr_cpus(counter); i++) {
> > > +		s = config->aggr_get_id(config, evsel__cpus(counter), i);
> > > +		if (cpu_map__compare_aggr_cpu_id(s, id))
> > > +			return true;
> > > +	}
> > > +
> > > +	return false;
> > > +}
> > > +
> > >   static void print_counter_aggrdata(struct perf_stat_config *config,
> > >   				   struct evsel *counter, int s,
> > >   				   char *prefix, bool metric_only,
> > > @@ -656,6 +670,12 @@ static void print_counter_aggrdata(struct perf_stat_config *config,
> > >   	double uval;
> > >   	ad.id = id = config->aggr_map->map[s];
> > > +
> > > +	if (perf_pmu__has_hybrid() &&
> > > +	    !aggr_id_hybrid_matched(config, counter, id)) {
> > > +		return;
> > > +	}
> > > +
> > >   	ad.val = ad.ena = ad.run = 0;
> > >   	ad.nr = 0;
> > >   	if (!collect_data(config, counter, aggr_cb, &ad))
> > 
> > there's same check in aggr_cb, so it seems like we could just make check in here:
> > 
> > 	if (perf_pmu__has_hybrid() && ad.ena == 0)
> > 		return;
> > 
> > without another extra loop
> > 
> > jirka
> > 
> 
> I guess you recommended the patch like this:
> 
>  static void print_counter_aggrdata(struct perf_stat_config *config,
>                                    struct evsel *counter, int s,
>                                    char *prefix, bool metric_only,
> @@ -670,17 +656,14 @@ static void print_counter_aggrdata(struct perf_stat_config *config,
>         double uval;
> 
>         ad.id = id = config->aggr_map->map[s];
>         ad.val = ad.ena = ad.run = 0;
>         ad.nr = 0;
>         if (!collect_data(config, counter, aggr_cb, &ad))
>                 return;
> 
> +       if (perf_pmu__has_hybrid() && ad.ena == 0)
> +               return;
> +
>         nr = ad.nr;
>         ena = ad.ena;
>         run = ad.run;
> 
> Yes, it works. The test log is,

ok, great

thanks,
jirka

> 
> # perf stat --per-core -e cpu_core/cycles/ -a -- sleep 1
> 
>  Performance counter stats for 'system wide':
> 
> S0-D0-C0           2          2,341,923      cpu_core/cycles/
> S0-D0-C4           2          1,707,933      cpu_core/cycles/
> S0-D0-C8           2            845,805      cpu_core/cycles/
> S0-D0-C12          2          1,001,961      cpu_core/cycles/
> S0-D0-C16          2            932,004      cpu_core/cycles/
> S0-D0-C20          2          1,778,603      cpu_core/cycles/
> S0-D0-C24          2            804,448      cpu_core/cycles/
> S0-D0-C28          2            178,360      cpu_core/cycles/
> 
>        1.002264168 seconds time elapsed
> 
> Thanks
> Jin Yao
>

Patch
diff mbox series

diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index 5255d78b1c30..15eafd249e46 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -643,6 +643,20 @@  static void aggr_cb(struct perf_stat_config *config,
 	}
 }
 
+static bool aggr_id_hybrid_matched(struct perf_stat_config *config,
+				   struct evsel *counter, struct aggr_cpu_id id)
+{
+	struct aggr_cpu_id s;
+
+	for (int i = 0; i < evsel__nr_cpus(counter); i++) {
+		s = config->aggr_get_id(config, evsel__cpus(counter), i);
+		if (cpu_map__compare_aggr_cpu_id(s, id))
+			return true;
+	}
+
+	return false;
+}
+
 static void print_counter_aggrdata(struct perf_stat_config *config,
 				   struct evsel *counter, int s,
 				   char *prefix, bool metric_only,
@@ -656,6 +670,12 @@  static void print_counter_aggrdata(struct perf_stat_config *config,
 	double uval;
 
 	ad.id = id = config->aggr_map->map[s];
+
+	if (perf_pmu__has_hybrid() &&
+	    !aggr_id_hybrid_matched(config, counter, id)) {
+		return;
+	}
+
 	ad.val = ad.ena = ad.run = 0;
 	ad.nr = 0;
 	if (!collect_data(config, counter, aggr_cb, &ad))