Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f2148330 authored by Namhyung Kim's avatar Namhyung Kim Committed by Jiri Olsa
Browse files

perf report: Add --percentage option



The --percentage option is for controlling overhead percentage
displayed.  It can only receive either of "relative" or "absolute".

"relative" means it's relative to filtered entries only so that the
sum of shown entries will be always 100%.  "absolute" means it retains
the original value before and after the filter is applied.

  $ perf report -s comm
  # Overhead       Command
  # ........  ............
  #
      74.19%           cc1
       7.61%           gcc
       6.11%            as
       4.35%            sh
       4.14%          make
       1.13%        fixdep
  ...

  $ perf report -s comm -c cc1,gcc --percentage absolute
  # Overhead       Command
  # ........  ............
  #
      74.19%           cc1
       7.61%           gcc

  $ perf report -s comm -c cc1,gcc --percentage relative
  # Overhead       Command
  # ........  ............
  #
      90.69%           cc1
       9.31%           gcc

Note that it has zero effect if no filter was applied.

Suggested-by: default avatarArnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/r/1397145720-8063-3-git-send-email-namhyung@kernel.org


Signed-off-by: default avatarJiri Olsa <jolsa@redhat.com>
parent 1ab1fa5d
Loading
Loading
Loading
Loading
+18 −6
Original line number Diff line number Diff line
@@ -25,10 +25,6 @@ OPTIONS
--verbose::
        Be more verbose. (show symbol address, etc)

-d::
--dsos=::
	Only consider symbols in these dsos. CSV that understands
	file://filename entries.
-n::
--show-nr-samples::
	Show the number of samples for each symbol
@@ -42,11 +38,18 @@ OPTIONS
-c::
--comms=::
	Only consider symbols in these comms. CSV that understands
	file://filename entries.
	file://filename entries.  This option will affect the percentage of
	the overhead column.  See --percentage for more info.
-d::
--dsos=::
	Only consider symbols in these dsos. CSV that understands
	file://filename entries.  This option will affect the percentage of
	the overhead column.  See --percentage for more info.
-S::
--symbols=::
	Only consider these symbols. CSV that understands
	file://filename entries.
	file://filename entries.  This option will affect the percentage of
	the overhead column.  See --percentage for more info.

--symbol-filter=::
	Only show symbols that match (partially) with this filter.
@@ -237,6 +240,15 @@ OPTIONS
	Do not show entries which have an overhead under that percent.
	(Default: 0).

--percentage::
	Determine how to display the overhead percentage of filtered entries.
	Filters can be applied by --comms, --dsos and/or --symbols options and
	Zoom operations on the TUI (thread, dso, etc).

	"relative" means it's relative to filtered entries only so that the
	sum of shown entries will be always 100%.  "absolute" means it retains
	the original value before and after the filter is applied.

--header::
	Show header information in the perf.data file.  This includes
	various information like hostname, OS and perf version, cpu/mem
+28 −2
Original line number Diff line number Diff line
@@ -343,6 +343,11 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report
	char buf[512];
	size_t size = sizeof(buf);

	if (symbol_conf.filter_relative) {
		nr_samples = hists->stats.nr_non_filtered_samples;
		nr_events = hists->stats.total_non_filtered_period;
	}

	if (perf_evsel__is_group_event(evsel)) {
		struct perf_evsel *pos;

@@ -350,10 +355,15 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report
		evname = buf;

		for_each_group_member(pos, evsel) {
			if (symbol_conf.filter_relative) {
				nr_samples += pos->hists.stats.nr_non_filtered_samples;
				nr_events += pos->hists.stats.total_non_filtered_period;
			} else {
				nr_samples += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE];
				nr_events += pos->hists.stats.total_period;
			}
		}
	}

	nr_samples = convert_unit(nr_samples, &unit);
	ret = fprintf(fp, "# Samples: %lu%c", nr_samples, unit);
@@ -707,6 +717,20 @@ parse_percent_limit(const struct option *opt, const char *str,
	return 0;
}

static int
parse_percentage(const struct option *opt __maybe_unused, const char *str,
		 int unset __maybe_unused)
{
	if (!strcmp(str, "relative"))
		symbol_conf.filter_relative = true;
	else if (!strcmp(str, "absolute"))
		symbol_conf.filter_relative = false;
	else
		return -1;

	return 0;
}

int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
{
	struct perf_session *session;
@@ -829,6 +853,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
	OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"),
	OPT_CALLBACK(0, "percent-limit", &report, "percent",
		     "Don't show entries under that percent", parse_percent_limit),
	OPT_CALLBACK(0, "percentage", NULL, "relative|absolute",
		     "how to display percentage of filtered entries", parse_percentage),
	OPT_END()
	};
	struct perf_data_file file = {
+27 −8
Original line number Diff line number Diff line
@@ -769,12 +769,15 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)

	for (nd = browser->top; nd; nd = rb_next(nd)) {
		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
		float percent = h->stat.period * 100.0 /
					hb->hists->stats.total_period;
		u64 total = hists__total_period(h->hists);
		float percent = 0.0;

		if (h->filtered)
			continue;

		if (total)
			percent = h->stat.period * 100.0 / total;

		if (percent < hb->min_pcnt)
			continue;

@@ -792,8 +795,11 @@ static struct rb_node *hists__filter_entries(struct rb_node *nd,
{
	while (nd != NULL) {
		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
		float percent = h->stat.period * 100.0 /
					hists->stats.total_period;
		u64 total = hists__total_period(hists);
		float percent = 0.0;

		if (total)
			percent = h->stat.period * 100.0 / total;

		if (percent < min_pcnt)
			return NULL;
@@ -813,8 +819,11 @@ static struct rb_node *hists__filter_prev_entries(struct rb_node *nd,
{
	while (nd != NULL) {
		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
		float percent = h->stat.period * 100.0 /
					hists->stats.total_period;
		u64 total = hists__total_period(hists);
		float percent = 0.0;

		if (total)
			percent = h->stat.period * 100.0 / total;

		if (!h->filtered && percent >= min_pcnt)
			return nd;
@@ -1189,6 +1198,11 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size,
	char buf[512];
	size_t buflen = sizeof(buf);

	if (symbol_conf.filter_relative) {
		nr_samples = hists->stats.nr_non_filtered_samples;
		nr_events = hists->stats.total_non_filtered_period;
	}

	if (perf_evsel__is_group_event(evsel)) {
		struct perf_evsel *pos;

@@ -1196,10 +1210,15 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size,
		ev_name = buf;

		for_each_group_member(pos, evsel) {
			if (symbol_conf.filter_relative) {
				nr_samples += pos->hists.stats.nr_non_filtered_samples;
				nr_events += pos->hists.stats.total_non_filtered_period;
			} else {
				nr_samples += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE];
				nr_events += pos->hists.stats.total_period;
			}
		}
	}

	nr_samples = convert_unit(nr_samples, &unit);
	printed = scnprintf(bf, size,
+5 −6
Original line number Diff line number Diff line
@@ -228,12 +228,15 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists,
	for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
		GtkTreeIter iter;
		float percent = h->stat.period * 100.0 /
					hists->stats.total_period;
		u64 total = hists__total_period(h->hists);
		float percent = 0.0;

		if (h->filtered)
			continue;

		if (total)
			percent = h->stat.period * 100.0 / total;

		if (percent < min_pcnt)
			continue;

@@ -261,12 +264,8 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists,
		}

		if (symbol_conf.use_callchain && sort__has_sym) {
			u64 total;

			if (callchain_param.mode == CHAIN_GRAPH_REL)
				total = h->stat.period;
			else
				total = hists->stats.total_period;

			perf_gtk__add_callchain(&h->sorted_chain, store, &iter,
						sym_col, total);
+4 −4
Original line number Diff line number Diff line
@@ -32,10 +32,10 @@ int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,

	if (fmt_percent) {
		double percent = 0.0;
		u64 total = hists__total_period(hists);

		if (hists->stats.total_period)
			percent = 100.0 * get_field(he) /
				  hists->stats.total_period;
		if (total)
			percent = 100.0 * get_field(he) / total;

		ret += hpp__call_print_fn(hpp, print_fn, fmt, percent);
	} else
@@ -50,7 +50,7 @@ int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,

		list_for_each_entry(pair, &he->pairs.head, pairs.node) {
			u64 period = get_field(pair);
			u64 total = pair->hists->stats.total_period;
			u64 total = hists__total_period(pair->hists);

			if (!total)
				continue;
Loading