Skip to content

Commit

Permalink
perf stat: Add cpu_aggr_map for loop
Browse files Browse the repository at this point in the history
Rename variables, add a comment and add a cpu_aggr_map__for_each_idx
to aid the readability of the stat-display code. In particular, try to
make sure aggr_idx is used consistently to differentiate from other
kinds of index.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Caleb Biggers <caleb.biggers@intel.com>
Cc: Eduard Zingerman <eddyz87@gmail.com>
Cc: Florian Fischer <florian.fischer@muhq.space>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jing Zhang <renyu.zj@linux.alibaba.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Perry Taylor <perry.taylor@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Sandipan Das <sandipan.das@amd.com>
Cc: Sean Christopherson <seanjc@google.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Link: https://lore.kernel.org/r/20230219092848.639226-49-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Ian Rogers authored and Arnaldo Carvalho de Melo committed Feb 19, 2023
1 parent cc26ffa commit 8945bef
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 125 deletions.
3 changes: 3 additions & 0 deletions tools/perf/util/cpumap.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ struct cpu_aggr_map {
struct aggr_cpu_id map[];
};

#define cpu_aggr_map__for_each_idx(idx, aggr_map) \
for ((idx) = 0; (idx) < aggr_map->nr; (idx)++)

struct perf_record_cpu_map_data;

bool perf_record_cpu_map_data__test_bit(int i, const struct perf_record_cpu_map_data *data);
Expand Down
112 changes: 58 additions & 54 deletions tools/perf/util/stat-display.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ static void print_cgroup(struct perf_stat_config *config, struct cgroup *cgrp)
}

static void print_aggr_id_std(struct perf_stat_config *config,
struct evsel *evsel, struct aggr_cpu_id id, int nr)
struct evsel *evsel, struct aggr_cpu_id id, int aggr_nr)
{
FILE *output = config->output;
int idx = config->aggr_mode;
Expand Down Expand Up @@ -225,31 +225,31 @@ static void print_aggr_id_std(struct perf_stat_config *config,
return;
}

fprintf(output, "%-*s %*d ", aggr_header_lens[idx], buf, 4, nr);
fprintf(output, "%-*s %*d ", aggr_header_lens[idx], buf, 4, aggr_nr);
}

static void print_aggr_id_csv(struct perf_stat_config *config,
struct evsel *evsel, struct aggr_cpu_id id, int nr)
struct evsel *evsel, struct aggr_cpu_id id, int aggr_nr)
{
FILE *output = config->output;
const char *sep = config->csv_sep;

switch (config->aggr_mode) {
case AGGR_CORE:
fprintf(output, "S%d-D%d-C%d%s%d%s",
id.socket, id.die, id.core, sep, nr, sep);
id.socket, id.die, id.core, sep, aggr_nr, sep);
break;
case AGGR_DIE:
fprintf(output, "S%d-D%d%s%d%s",
id.socket, id.die, sep, nr, sep);
id.socket, id.die, sep, aggr_nr, sep);
break;
case AGGR_SOCKET:
fprintf(output, "S%d%s%d%s",
id.socket, sep, nr, sep);
id.socket, sep, aggr_nr, sep);
break;
case AGGR_NODE:
fprintf(output, "N%d%s%d%s",
id.node, sep, nr, sep);
id.node, sep, aggr_nr, sep);
break;
case AGGR_NONE:
if (evsel->percore && !config->percore_show_thread) {
Expand All @@ -275,26 +275,26 @@ static void print_aggr_id_csv(struct perf_stat_config *config,
}

static void print_aggr_id_json(struct perf_stat_config *config,
struct evsel *evsel, struct aggr_cpu_id id, int nr)
struct evsel *evsel, struct aggr_cpu_id id, int aggr_nr)
{
FILE *output = config->output;

switch (config->aggr_mode) {
case AGGR_CORE:
fprintf(output, "\"core\" : \"S%d-D%d-C%d\", \"aggregate-number\" : %d, ",
id.socket, id.die, id.core, nr);
id.socket, id.die, id.core, aggr_nr);
break;
case AGGR_DIE:
fprintf(output, "\"die\" : \"S%d-D%d\", \"aggregate-number\" : %d, ",
id.socket, id.die, nr);
id.socket, id.die, aggr_nr);
break;
case AGGR_SOCKET:
fprintf(output, "\"socket\" : \"S%d\", \"aggregate-number\" : %d, ",
id.socket, nr);
id.socket, aggr_nr);
break;
case AGGR_NODE:
fprintf(output, "\"node\" : \"N%d\", \"aggregate-number\" : %d, ",
id.node, nr);
id.node, aggr_nr);
break;
case AGGR_NONE:
if (evsel->percore && !config->percore_show_thread) {
Expand All @@ -319,14 +319,14 @@ static void print_aggr_id_json(struct perf_stat_config *config,
}

static void aggr_printout(struct perf_stat_config *config,
struct evsel *evsel, struct aggr_cpu_id id, int nr)
struct evsel *evsel, struct aggr_cpu_id id, int aggr_nr)
{
if (config->json_output)
print_aggr_id_json(config, evsel, id, nr);
print_aggr_id_json(config, evsel, id, aggr_nr);
else if (config->csv_output)
print_aggr_id_csv(config, evsel, id, nr);
print_aggr_id_csv(config, evsel, id, aggr_nr);
else
print_aggr_id_std(config, evsel, id, nr);
print_aggr_id_std(config, evsel, id, aggr_nr);
}

struct outstate {
Expand All @@ -335,7 +335,7 @@ struct outstate {
bool first;
const char *prefix;
int nfields;
int nr;
int aggr_nr;
struct aggr_cpu_id id;
struct evsel *evsel;
struct cgroup *cgrp;
Expand All @@ -355,7 +355,7 @@ static void do_new_line_std(struct perf_stat_config *config,
fputc('\n', os->fh);
if (os->prefix)
fputs(os->prefix, os->fh);
aggr_printout(config, os->evsel, os->id, os->nr);
aggr_printout(config, os->evsel, os->id, os->aggr_nr);
if (config->aggr_mode == AGGR_NONE)
fprintf(os->fh, " ");
fprintf(os->fh, " ");
Expand Down Expand Up @@ -396,7 +396,7 @@ static void new_line_csv(struct perf_stat_config *config, void *ctx)
fputc('\n', os->fh);
if (os->prefix)
fprintf(os->fh, "%s", os->prefix);
aggr_printout(config, os->evsel, os->id, os->nr);
aggr_printout(config, os->evsel, os->id, os->aggr_nr);
for (i = 0; i < os->nfields; i++)
fputs(config->csv_sep, os->fh);
}
Expand Down Expand Up @@ -444,7 +444,7 @@ static void new_line_json(struct perf_stat_config *config, void *ctx)
fputs("\n{", os->fh);
if (os->prefix)
fprintf(os->fh, "%s", os->prefix);
aggr_printout(config, os->evsel, os->id, os->nr);
aggr_printout(config, os->evsel, os->id, os->aggr_nr);
}

/* Filter out some columns that don't work well in metrics only mode */
Expand Down Expand Up @@ -645,10 +645,10 @@ static void print_counter_value(struct perf_stat_config *config,
}

static void abs_printout(struct perf_stat_config *config,
struct aggr_cpu_id id, int nr,
struct aggr_cpu_id id, int aggr_nr,
struct evsel *evsel, double avg, bool ok)
{
aggr_printout(config, evsel, id, nr);
aggr_printout(config, evsel, id, aggr_nr);
print_counter_value(config, evsel, avg, ok);
print_cgroup(config, evsel->cgrp);
}
Expand Down Expand Up @@ -678,7 +678,7 @@ static bool is_mixed_hw_group(struct evsel *counter)
}

static void printout(struct perf_stat_config *config, struct outstate *os,
double uval, u64 run, u64 ena, double noise, int map_idx)
double uval, u64 run, u64 ena, double noise, int aggr_idx)
{
struct perf_stat_output_ctx out;
print_metric_t pm;
Expand Down Expand Up @@ -721,14 +721,14 @@ static void printout(struct perf_stat_config *config, struct outstate *os,
out.force_header = false;

if (!config->metric_only) {
abs_printout(config, os->id, os->nr, counter, uval, ok);
abs_printout(config, os->id, os->aggr_nr, counter, uval, ok);

print_noise(config, counter, noise, /*before_metric=*/true);
print_running(config, run, ena, /*before_metric=*/true);
}

if (ok) {
perf_stat__print_shadow_stats(config, counter, uval, map_idx,
perf_stat__print_shadow_stats(config, counter, uval, aggr_idx,
&out, &config->metric_events);
} else {
pm(config, os, /*color=*/NULL, /*format=*/NULL, /*unit=*/"", /*val=*/0);
Expand Down Expand Up @@ -833,20 +833,20 @@ static bool should_skip_zero_counter(struct perf_stat_config *config,
}

static void print_counter_aggrdata(struct perf_stat_config *config,
struct evsel *counter, int s,
struct evsel *counter, int aggr_idx,
struct outstate *os)
{
FILE *output = config->output;
u64 ena, run, val;
double uval;
struct perf_stat_evsel *ps = counter->stats;
struct perf_stat_aggr *aggr = &ps->aggr[s];
struct aggr_cpu_id id = config->aggr_map->map[s];
struct perf_stat_aggr *aggr = &ps->aggr[aggr_idx];
struct aggr_cpu_id id = config->aggr_map->map[aggr_idx];
double avg = aggr->counts.val;
bool metric_only = config->metric_only;

os->id = id;
os->nr = aggr->nr;
os->aggr_nr = aggr->nr;
os->evsel = counter;

/* Skip already merged uncore/hybrid events */
Expand Down Expand Up @@ -874,7 +874,7 @@ static void print_counter_aggrdata(struct perf_stat_config *config,

uval = val * counter->scale;

printout(config, os, uval, run, ena, avg, s);
printout(config, os, uval, run, ena, avg, aggr_idx);

if (!metric_only)
fputc('\n', output);
Expand Down Expand Up @@ -925,7 +925,7 @@ static void print_aggr(struct perf_stat_config *config,
struct outstate *os)
{
struct evsel *counter;
int s;
int aggr_idx;

if (!config->aggr_map || !config->aggr_get_id)
return;
Expand All @@ -934,11 +934,11 @@ static void print_aggr(struct perf_stat_config *config,
* With metric_only everything is on a single line.
* Without each counter has its own line.
*/
for (s = 0; s < config->aggr_map->nr; s++) {
print_metric_begin(config, evlist, os, s);
cpu_aggr_map__for_each_idx(aggr_idx, config->aggr_map) {
print_metric_begin(config, evlist, os, aggr_idx);

evlist__for_each_entry(evlist, counter) {
print_counter_aggrdata(config, counter, s, os);
print_counter_aggrdata(config, counter, aggr_idx, os);
}
print_metric_end(config, os);
}
Expand All @@ -949,7 +949,7 @@ static void print_aggr_cgroup(struct perf_stat_config *config,
struct outstate *os)
{
struct evsel *counter, *evsel;
int s;
int aggr_idx;

if (!config->aggr_map || !config->aggr_get_id)
return;
Expand All @@ -960,14 +960,14 @@ static void print_aggr_cgroup(struct perf_stat_config *config,

os->cgrp = evsel->cgrp;

for (s = 0; s < config->aggr_map->nr; s++) {
print_metric_begin(config, evlist, os, s);
cpu_aggr_map__for_each_idx(aggr_idx, config->aggr_map) {
print_metric_begin(config, evlist, os, aggr_idx);

evlist__for_each_entry(evlist, counter) {
if (counter->cgrp != os->cgrp)
continue;

print_counter_aggrdata(config, counter, s, os);
print_counter_aggrdata(config, counter, aggr_idx, os);
}
print_metric_end(config, os);
}
Expand All @@ -977,14 +977,14 @@ static void print_aggr_cgroup(struct perf_stat_config *config,
static void print_counter(struct perf_stat_config *config,
struct evsel *counter, struct outstate *os)
{
int s;
int aggr_idx;

/* AGGR_THREAD doesn't have config->aggr_get_id */
if (!config->aggr_map)
return;

for (s = 0; s < config->aggr_map->nr; s++) {
print_counter_aggrdata(config, counter, s, os);
cpu_aggr_map__for_each_idx(aggr_idx, config->aggr_map) {
print_counter_aggrdata(config, counter, aggr_idx, os);
}
}

Expand All @@ -1003,23 +1003,23 @@ static void print_no_aggr_metric(struct perf_stat_config *config,
u64 ena, run, val;
double uval;
struct perf_stat_evsel *ps = counter->stats;
int counter_idx = perf_cpu_map__idx(evsel__cpus(counter), cpu);
int aggr_idx = perf_cpu_map__idx(evsel__cpus(counter), cpu);

if (counter_idx < 0)
if (aggr_idx < 0)
continue;

os->evsel = counter;
os->id = aggr_cpu_id__cpu(cpu, /*data=*/NULL);
if (first) {
print_metric_begin(config, evlist, os, counter_idx);
print_metric_begin(config, evlist, os, aggr_idx);
first = false;
}
val = ps->aggr[counter_idx].counts.val;
ena = ps->aggr[counter_idx].counts.ena;
run = ps->aggr[counter_idx].counts.run;
val = ps->aggr[aggr_idx].counts.val;
ena = ps->aggr[aggr_idx].counts.ena;
run = ps->aggr[aggr_idx].counts.run;

uval = val * counter->scale;
printout(config, os, uval, run, ena, 1.0, counter_idx);
printout(config, os, uval, run, ena, 1.0, aggr_idx);
}
if (!first)
print_metric_end(config, os);
Expand Down Expand Up @@ -1338,26 +1338,30 @@ static void print_percore(struct perf_stat_config *config,
bool metric_only = config->metric_only;
FILE *output = config->output;
struct cpu_aggr_map *core_map;
int s, c, i;
int aggr_idx, core_map_len = 0;

if (!config->aggr_map || !config->aggr_get_id)
return;

if (config->percore_show_thread)
return print_counter(config, counter, os);

/*
* core_map will hold the aggr_cpu_id for the cores that have been
* printed so that each core is printed just once.
*/
core_map = cpu_aggr_map__empty_new(config->aggr_map->nr);
if (core_map == NULL) {
fprintf(output, "Cannot allocate per-core aggr map for display\n");
return;
}

for (s = 0, c = 0; s < config->aggr_map->nr; s++) {
struct perf_cpu curr_cpu = config->aggr_map->map[s].cpu;
cpu_aggr_map__for_each_idx(aggr_idx, config->aggr_map) {
struct perf_cpu curr_cpu = config->aggr_map->map[aggr_idx].cpu;
struct aggr_cpu_id core_id = aggr_cpu_id__core(curr_cpu, NULL);
bool found = false;

for (i = 0; i < c; i++) {
for (int i = 0; i < core_map_len; i++) {
if (aggr_cpu_id__equal(&core_map->map[i], &core_id)) {
found = true;
break;
Expand All @@ -1366,9 +1370,9 @@ static void print_percore(struct perf_stat_config *config,
if (found)
continue;

print_counter_aggrdata(config, counter, s, os);
print_counter_aggrdata(config, counter, aggr_idx, os);

core_map->map[c++] = core_id;
core_map->map[core_map_len++] = core_id;
}
free(core_map);

Expand Down
Loading

0 comments on commit 8945bef

Please sign in to comment.