Skip to content

Commit 4fc4d8d

Browse files
Jin Yaoacmel
authored andcommitted
perf stat: Support 'percore' event qualifier
With this patch, we can use the 'percore' event qualifier in perf-stat. root@skl:/tmp# perf stat -e cpu/event=0,umask=0x3,percore=1/,cpu/event=0,umask=0x3/ -a -A -I1000 1.000773050 S0-C0 98,352,832 cpu/event=0,umask=0x3,percore=1/ (50.01%) 1.000773050 S0-C1 103,763,057 cpu/event=0,umask=0x3,percore=1/ (50.02%) 1.000773050 S0-C2 196,776,995 cpu/event=0,umask=0x3,percore=1/ (50.02%) 1.000773050 S0-C3 176,493,779 cpu/event=0,umask=0x3,percore=1/ (50.02%) 1.000773050 CPU0 47,699,641 cpu/event=0,umask=0x3/ (50.02%) 1.000773050 CPU1 49,052,451 cpu/event=0,umask=0x3/ (49.98%) 1.000773050 CPU2 102,771,422 cpu/event=0,umask=0x3/ (49.98%) 1.000773050 CPU3 100,784,662 cpu/event=0,umask=0x3/ (49.98%) 1.000773050 CPU4 43,171,342 cpu/event=0,umask=0x3/ (49.98%) 1.000773050 CPU5 54,152,158 cpu/event=0,umask=0x3/ (49.98%) 1.000773050 CPU6 93,618,410 cpu/event=0,umask=0x3/ (49.98%) 1.000773050 CPU7 74,477,589 cpu/event=0,umask=0x3/ (49.99%) In this example, we count the event 'ref-cycles' per-core and per-CPU in one perf stat command-line. From the output, we can see: S0-C0 = CPU0 + CPU4 S0-C1 = CPU1 + CPU5 S0-C2 = CPU2 + CPU6 S0-C3 = CPU3 + CPU7 So the result is expected (tiny difference is ignored). Note that, the 'percore' event qualifier needs to use with option '-A'. Signed-off-by: Jin Yao <[email protected]> Tested-by: Ravi Bangoria <[email protected]> Acked-by: Jiri Olsa <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Jin Yao <[email protected]> Cc: Kan Liang <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 40480a8 commit 4fc4d8d

File tree

4 files changed

+69
-7
lines changed

4 files changed

+69
-7
lines changed

tools/perf/Documentation/perf-stat.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ report::
4343
param1 and param2 are defined as formats for the PMU in
4444
/sys/bus/event_source/devices/<pmu>/format/*
4545

46+
'percore' is a event qualifier that sums up the event counts for both
47+
hardware threads in a core. For example:
48+
perf stat -A -a -e cpu/event,percore=1/,otherevent ...
49+
4650
- a symbolically formed event like 'pmu/config=M,config1=N,config2=K/'
4751
where M, N, K are numbers (in decimal, hex, octal format).
4852
Acceptable values for each of 'config', 'config1' and 'config2'

tools/perf/builtin-stat.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,18 @@ static int perf_stat__get_core_cached(struct perf_stat_config *config,
847847
return perf_stat__get_aggr(config, perf_stat__get_core, map, idx);
848848
}
849849

850+
static bool term_percore_set(void)
851+
{
852+
struct perf_evsel *counter;
853+
854+
evlist__for_each_entry(evsel_list, counter) {
855+
if (counter->percore)
856+
return true;
857+
}
858+
859+
return false;
860+
}
861+
850862
static int perf_stat_init_aggr_mode(void)
851863
{
852864
int nr;
@@ -867,6 +879,15 @@ static int perf_stat_init_aggr_mode(void)
867879
stat_config.aggr_get_id = perf_stat__get_core_cached;
868880
break;
869881
case AGGR_NONE:
882+
if (term_percore_set()) {
883+
if (cpu_map__build_core_map(evsel_list->cpus,
884+
&stat_config.aggr_map)) {
885+
perror("cannot build core map");
886+
return -1;
887+
}
888+
stat_config.aggr_get_id = perf_stat__get_core_cached;
889+
}
890+
break;
870891
case AGGR_GLOBAL:
871892
case AGGR_THREAD:
872893
case AGGR_UNSET:

tools/perf/util/stat-display.c

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,17 @@ static void aggr_printout(struct perf_stat_config *config,
8888
config->csv_sep);
8989
break;
9090
case AGGR_NONE:
91-
fprintf(config->output, "CPU%*d%s",
92-
config->csv_output ? 0 : -4,
93-
perf_evsel__cpus(evsel)->map[id], config->csv_sep);
91+
if (evsel->percore) {
92+
fprintf(config->output, "S%d-C%*d%s",
93+
cpu_map__id_to_socket(id),
94+
config->csv_output ? 0 : -5,
95+
cpu_map__id_to_cpu(id), config->csv_sep);
96+
} else {
97+
fprintf(config->output, "CPU%*d%s ",
98+
config->csv_output ? 0 : -5,
99+
perf_evsel__cpus(evsel)->map[id],
100+
config->csv_sep);
101+
}
94102
break;
95103
case AGGR_THREAD:
96104
fprintf(config->output, "%*s-%*d%s",
@@ -1103,6 +1111,30 @@ static void print_footer(struct perf_stat_config *config)
11031111
"the same PMU. Try reorganizing the group.\n");
11041112
}
11051113

1114+
static void print_percore(struct perf_stat_config *config,
1115+
struct perf_evsel *counter, char *prefix)
1116+
{
1117+
bool metric_only = config->metric_only;
1118+
FILE *output = config->output;
1119+
int s;
1120+
bool first = true;
1121+
1122+
if (!(config->aggr_map || config->aggr_get_id))
1123+
return;
1124+
1125+
for (s = 0; s < config->aggr_map->nr; s++) {
1126+
if (prefix && metric_only)
1127+
fprintf(output, "%s", prefix);
1128+
1129+
print_counter_aggrdata(config, counter, s,
1130+
prefix, metric_only,
1131+
&first);
1132+
}
1133+
1134+
if (metric_only)
1135+
fputc('\n', output);
1136+
}
1137+
11061138
void
11071139
perf_evlist__print_counters(struct perf_evlist *evlist,
11081140
struct perf_stat_config *config,
@@ -1153,7 +1185,10 @@ perf_evlist__print_counters(struct perf_evlist *evlist,
11531185
print_no_aggr_metric(config, evlist, prefix);
11541186
else {
11551187
evlist__for_each_entry(evlist, counter) {
1156-
print_counter(config, counter, prefix);
1188+
if (counter->percore)
1189+
print_percore(config, counter, prefix);
1190+
else
1191+
print_counter(config, counter, prefix);
11571192
}
11581193
}
11591194
break;

tools/perf/util/stat.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,11 @@ process_counter_values(struct perf_stat_config *config, struct perf_evsel *evsel
277277
if (!evsel->snapshot)
278278
perf_evsel__compute_deltas(evsel, cpu, thread, count);
279279
perf_counts_values__scale(count, config->scale, NULL);
280-
if (config->aggr_mode == AGGR_NONE)
281-
perf_stat__update_shadow_stats(evsel, count->val, cpu,
282-
&rt_stat);
280+
if ((config->aggr_mode == AGGR_NONE) && (!evsel->percore)) {
281+
perf_stat__update_shadow_stats(evsel, count->val,
282+
cpu, &rt_stat);
283+
}
284+
283285
if (config->aggr_mode == AGGR_THREAD) {
284286
if (config->stats)
285287
perf_stat__update_shadow_stats(evsel,

0 commit comments

Comments
 (0)