Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1250418 > unrolled thread

[PATCH 00/14] perf bench: Misc improvements

Started byIngo Molnar <mingo@kernel.org>
First post2015-10-19 10:10 +0200
Last post2015-10-19 21:10 +0200
Articles 20 on this page of 44 — 5 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 00/14] perf bench: Misc improvements Ingo Molnar <mingo@kernel.org> - 2015-10-19 10:10 +0200
    [PATCH 12/14] perf/bench: Harmonize all the -l/--nr_loops options Ingo Molnar <mingo@kernel.org> - 2015-10-19 10:10 +0200
      [tip:perf/core] perf bench: Harmonize all the -l/  --nr_loops options tip-bot for Ingo Molnar <tipbot@zytor.com> - 2015-10-20 09:50 +0200
    [PATCH 09/14] perf/bench/mem: Fix 'length' vs. 'size' naming confusion Ingo Molnar <mingo@kernel.org> - 2015-10-19 10:10 +0200
      [tip:perf/core] perf bench mem: Fix 'length' vs. 'size'   naming confusion tip-bot for Ingo Molnar <tipbot@zytor.com> - 2015-10-20 09:50 +0200
    [PATCH 07/14] perf/bench/mem: Change 'cycle' to 'cycles' Ingo Molnar <mingo@kernel.org> - 2015-10-19 10:10 +0200
      [tip:perf/core] perf bench mem: Change 'cycle' to 'cycles' tip-bot for Ingo Molnar <tipbot@zytor.com> - 2015-10-20 09:50 +0200
    [PATCH 14/14] perf/bench: Run benchmarks, don't test them Ingo Molnar <mingo@kernel.org> - 2015-10-19 10:10 +0200
      [tip:perf/core] perf bench: Run benchmarks, don't test them tip-bot for Ingo Molnar <tipbot@zytor.com> - 2015-10-20 09:50 +0200
    [PATCH 10/14] perf/bench/mem: Improve user visible strings Ingo Molnar <mingo@kernel.org> - 2015-10-19 10:10 +0200
      [tip:perf/core] perf bench mem: Improve user visible strings tip-bot for Ingo Molnar <tipbot@zytor.com> - 2015-10-20 09:50 +0200
    [PATCH 11/14] perf/bench/mem: Reorganize the code a bit Ingo Molnar <mingo@kernel.org> - 2015-10-19 10:10 +0200
      [tip:perf/core] perf bench mem: Reorganize the code a bit tip-bot for Ingo Molnar <tipbot@zytor.com> - 2015-10-20 09:50 +0200
    [PATCH 13/14] perf/bench/mem: Rename 'routine' to 'function' Ingo Molnar <mingo@kernel.org> - 2015-10-19 10:10 +0200
      [tip:perf/core] perf bench mem: Rename 'routine' to 'function' tip-bot for Ingo Molnar <tipbot@zytor.com> - 2015-10-20 09:50 +0200
    [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str' Ingo Molnar <mingo@kernel.org> - 2015-10-19 10:10 +0200
      Re: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str' David Ahern <dsahern@gmail.com> - 2015-10-19 15:40 +0200
        Re: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str' Arnaldo Carvalho de Melo <acme@redhat.com> - 2015-10-19 21:00 +0200
          Re: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str' Arnaldo Carvalho de Melo <acme@redhat.com> - 2015-10-19 21:00 +0200
            Re: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str' Ingo Molnar <mingo@kernel.org> - 2015-10-19 21:10 +0200
              Re: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str' Arnaldo Carvalho de Melo <acme@redhat.com> - 2015-10-19 21:30 +0200
                Re: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str' Arnaldo Carvalho de Melo <acme@redhat.com> - 2015-10-19 21:30 +0200
                  Re: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str' Ingo Molnar <mingo@kernel.org> - 2015-10-20 09:40 +0200
      [tip:perf/core] perf bench mem: Rename 'routine' to 'routine_str' tip-bot for Ingo Molnar <tipbot@zytor.com> - 2015-10-20 09:50 +0200
    [PATCH 02/14] perf/bench: Default to all routines in 'perf bench mem' Ingo Molnar <mingo@kernel.org> - 2015-10-19 10:20 +0200
      Re: [PATCH 02/14] perf/bench: Default to all routines in 'perf bench mem' Linus Torvalds <torvalds@linux-foundation.org> - 2015-10-19 17:30 +0200
        Re: [PATCH 02/14] perf/bench: Default to all routines in 'perf bench  mem' Ingo Molnar <mingo@kernel.org> - 2015-10-19 19:50 +0200
      [tip:perf/core] perf bench: Default to all routines in '  perf bench mem' tip-bot for Ingo Molnar <tipbot@zytor.com> - 2015-10-20 09:50 +0200
    [PATCH 06/14] perf/bench: List output formatting options on 'perf bench -h' Ingo Molnar <mingo@kernel.org> - 2015-10-19 10:20 +0200
      Re: [PATCH 06/14] perf/bench: List output formatting options on 'perf  bench -h' David Ahern <dsahern@gmail.com> - 2015-10-19 15:30 +0200
        Re: [PATCH 06/14] perf/bench: List output formatting options on  'perf bench -h' Arnaldo Carvalho de Melo <acme@redhat.com> - 2015-10-19 21:00 +0200
      [tip:perf/core] perf bench: List output formatting options on '  perf bench -h' tip-bot for Ingo Molnar <tipbot@zytor.com> - 2015-10-20 09:50 +0200
    [PATCH 05/14] perf/bench: Remove the prefaulting complication from 'perf bench mem mem*' Ingo Molnar <mingo@kernel.org> - 2015-10-19 10:20 +0200
      [tip:perf/core] perf bench:   Remove the prefaulting complication from 'perf bench mem mem*' tip-bot for Ingo Molnar <tipbot@zytor.com> - 2015-10-20 09:50 +0200
    [PATCH 04/14] perf/bench: Rename 'mem-memcpy.c' => 'mem-functions.c' Ingo Molnar <mingo@kernel.org> - 2015-10-19 10:20 +0200
      Re: [PATCH 04/14] perf/bench: Rename 'mem-memcpy.c' =>  'mem-functions.c' Arnaldo Carvalho de Melo <acme@redhat.com> - 2015-10-19 20:40 +0200
      Re: [PATCH 04/14] perf/bench: Rename 'mem-memcpy.c' =>  'mem-functions.c' Arnaldo Carvalho de Melo <acme@redhat.com> - 2015-10-19 20:40 +0200
      [tip:perf/core] perf bench: Rename 'mem-memcpy.c' => '  mem-functions.c' tip-bot for Ingo Molnar <tipbot@zytor.com> - 2015-10-20 09:50 +0200
    [PATCH 03/14] perf/bench: Eliminate unused argument from bench_mem_common() Ingo Molnar <mingo@kernel.org> - 2015-10-19 10:20 +0200
      [tip:perf/core] perf bench:   Eliminate unused argument from bench_mem_common() tip-bot for Ingo Molnar <tipbot@zytor.com> - 2015-10-20 09:50 +0200
    [PATCH 01/14] perf/bench: Improve the 'perf bench mem memcpy' code readability Ingo Molnar <mingo@kernel.org> - 2015-10-19 10:20 +0200
      [tip:perf/core] perf bench: Improve the 'perf bench mem memcpy'   code readability tip-bot for Ingo Molnar <tipbot@zytor.com> - 2015-10-20 09:50 +0200
    Re: [PATCH 00/14] perf bench: Misc improvements David Ahern <dsahern@gmail.com> - 2015-10-19 15:50 +0200
      Re: [PATCH 00/14] perf bench: Misc improvements Arnaldo Carvalho de Melo <acme@redhat.com> - 2015-10-19 21:10 +0200

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#1251025 — Re: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str'

FromArnaldo Carvalho de Melo <acme@redhat.com>
Date2015-10-19 21:30 +0200
SubjectRe: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str'
Message-ID<qloi5-5w7-13@gated-at.bofh.it>
In reply to#1251016
Em Mon, Oct 19, 2015 at 09:09:32PM +0200, Ingo Molnar escreveu:
> 
> * Arnaldo Carvalho de Melo <acme@redhat.com> wrote:
> 
> > Em Mon, Oct 19, 2015 at 04:54:47PM -0200, Arnaldo Carvalho de Melo escreveu:
> > > Em Mon, Oct 19, 2015 at 07:34:46AM -0600, David Ahern escreveu:
> > > > On 10/19/15 2:04 AM, Ingo Molnar wrote:
> > > > >@@ -128,7 +128,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l
> > > > >  	double result_bps = 0.0;
> > > > >  	u64 result_cycles = 0;
> > > > >
> > > > >-	printf("Routine %s (%s)\n", r->name, r->desc);
> > > > >+	printf("routine %s (%s)\n", r->name, r->desc);
> > > > >
> > > > >  	if (bench_format == BENCH_FORMAT_DEFAULT)
> > > > >  		printf("# Copying %s Bytes ...\n\n", length_str);
> > > > 
> > > > Seems like 'R' is more appropriate here.
> > > 
> > > Right, changed it.
> > 
> > And then, he does that on a later patch, duh.
> 
> Yeah, indeed - I messed that up: tried to introduce __unused but noticed during 
> development and testing on other distros that '__unused' is way too crowded a 
> namespace (various fields in random headers are named like that), so after a bit 
> of a fight with those headers I changed it back to __maybe_unused ... but the 
> original change slipped into the series.
> 
> Do you want me to resend the series to fix this and the other problems David and 
> you noticed?

No problem, I fixed it all already :-)

- Arnaldo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1251028 — Re: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str'

FromArnaldo Carvalho de Melo <acme@redhat.com>
Date2015-10-19 21:30 +0200
SubjectRe: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str'
Message-ID<qloi6-5w7-35@gated-at.bofh.it>
In reply to#1251025
Em Mon, Oct 19, 2015 at 05:20:03PM -0200, Arnaldo Carvalho de Melo escreveu:
> Em Mon, Oct 19, 2015 at 09:09:32PM +0200, Ingo Molnar escreveu:
> > * Arnaldo Carvalho de Melo <acme@redhat.com> wrote:
> > > Em Mon, Oct 19, 2015 at 04:54:47PM -0200, Arnaldo Carvalho de Melo escreveu:
> > > > Em Mon, Oct 19, 2015 at 07:34:46AM -0600, David Ahern escreveu:
> > > > > Seems like 'R' is more appropriate here.

> > > > Right, changed it.

> > > And then, he does that on a later patch, duh.

> > Yeah, indeed - I messed that up: tried to introduce __unused but noticed during 
> > development and testing on other distros that '__unused' is way too crowded a 
> > namespace (various fields in random headers are named like that), so after a bit 
> > of a fight with those headers I changed it back to __maybe_unused ... but the 
> > original change slipped into the series.
> > 
> > Do you want me to resend the series to fix this and the other problems David and 
> > you noticed?
> 
> No problem, I fixed it all already :-)

Please check my perf/core branch.

- Arnaldo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1251357 — Re: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str'

FromIngo Molnar <mingo@kernel.org>
Date2015-10-20 09:40 +0200
SubjectRe: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str'
Message-ID<qlzGy-5pm-41@gated-at.bofh.it>
In reply to#1251028
* Arnaldo Carvalho de Melo <acme@redhat.com> wrote:

> Em Mon, Oct 19, 2015 at 05:20:03PM -0200, Arnaldo Carvalho de Melo escreveu:
> > Em Mon, Oct 19, 2015 at 09:09:32PM +0200, Ingo Molnar escreveu:
> > > * Arnaldo Carvalho de Melo <acme@redhat.com> wrote:
> > > > Em Mon, Oct 19, 2015 at 04:54:47PM -0200, Arnaldo Carvalho de Melo escreveu:
> > > > > Em Mon, Oct 19, 2015 at 07:34:46AM -0600, David Ahern escreveu:
> > > > > > Seems like 'R' is more appropriate here.
> 
> > > > > Right, changed it.
> 
> > > > And then, he does that on a later patch, duh.
> 
> > > Yeah, indeed - I messed that up: tried to introduce __unused but noticed during 
> > > development and testing on other distros that '__unused' is way too crowded a 
> > > namespace (various fields in random headers are named like that), so after a bit 
> > > of a fight with those headers I changed it back to __maybe_unused ... but the 
> > > original change slipped into the series.
> > > 
> > > Do you want me to resend the series to fix this and the other problems David and 
> > > you noticed?
> > 
> > No problem, I fixed it all already :-)
> 
> Please check my perf/core branch.

Looks good - thanks Arnaldo!

	Ingo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1251381 — [tip:perf/core] perf bench mem: Rename 'routine' to 'routine_str'

Fromtip-bot for Ingo Molnar <tipbot@zytor.com>
Date2015-10-20 09:50 +0200
Subject[tip:perf/core] perf bench mem: Rename 'routine' to 'routine_str'
Message-ID<qlzQf-5Bb-43@gated-at.bofh.it>
In reply to#1250430
Commit-ID:  e815e327604af880bdcf38cdd711dfa78627ab2a
Gitweb:     http://git.kernel.org/tip/e815e327604af880bdcf38cdd711dfa78627ab2a
Author:     Ingo Molnar <mingo@kernel.org>
AuthorDate: Mon, 19 Oct 2015 10:04:24 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 19 Oct 2015 16:05:27 -0300

perf bench mem: Rename 'routine' to 'routine_str'

So bench/mem-functions.c has a 'routine' name for the routines parameter
string, but a 'length_str' name for the length parameter string.

We also have another entity named 'routine': 'struct routine'.

This is inconsistent and confusing: rename 'routine' to 'routine_str'.

Also fix typos in the --routine help text.

Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1445241870-24854-9-git-send-email-mingo@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/bench/mem-functions.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c
index 6fe8667..a76e57f 100644
--- a/tools/perf/bench/mem-functions.c
+++ b/tools/perf/bench/mem-functions.c
@@ -24,7 +24,7 @@
 #define K 1024
 
 static const char	*length_str	= "1MB";
-static const char	*routine	= "all";
+static const char	*routine_str	= "all";
 static int		iterations	= 1;
 static bool		use_cycles;
 static int		cycles_fd;
@@ -33,8 +33,8 @@ static const struct option options[] = {
 	OPT_STRING('l', "length", &length_str, "1MB",
 		    "Specify length of memory to copy. "
 		    "Available units: B, KB, MB, GB and TB (upper and lower)"),
-	OPT_STRING('r', "routine", &routine, "all",
-		    "Specify routine to copy, \"all\" runs all available routines"),
+	OPT_STRING('r', "routine", &routine_str, "all",
+		    "Specify the routine to run, \"all\" runs all available routines"),
 	OPT_INTEGER('i', "iterations", &iterations,
 		    "repeat memcpy() invocation this number of times"),
 	OPT_BOOLEAN('c', "cycles", &use_cycles,
@@ -181,18 +181,18 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *
 		return 1;
 	}
 
-	if (!strncmp(routine, "all", 3)) {
+	if (!strncmp(routine_str, "all", 3)) {
 		for (i = 0; info->routines[i].name; i++)
 			__bench_mem_routine(info, i, len, totallen);
 		return 0;
 	}
 
 	for (i = 0; info->routines[i].name; i++) {
-		if (!strcmp(info->routines[i].name, routine))
+		if (!strcmp(info->routines[i].name, routine_str))
 			break;
 	}
 	if (!info->routines[i].name) {
-		printf("Unknown routine:%s\n", routine);
+		printf("Unknown routine: %s\n", routine_str);
 		printf("Available routines...\n");
 		for (i = 0; info->routines[i].name; i++) {
 			printf("\t%s ... %s\n",
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1250433 — [PATCH 02/14] perf/bench: Default to all routines in 'perf bench mem'

FromIngo Molnar <mingo@kernel.org>
Date2015-10-19 10:20 +0200
Subject[PATCH 02/14] perf/bench: Default to all routines in 'perf bench mem'
Message-ID<qldPH-74y-5@gated-at.bofh.it>
In reply to#1250418
So few people know that the --routine option to 'perf bench memcpy/memset' exists,
and would not know that it's capable of testing the kernel's memcpy/memset
implementations.

Furthermore, 'perf bench mem all' will not run all routines:

	vega:~> perf bench mem all
	# Running mem/memcpy benchmark...
	Routine default (Default memcpy() provided by glibc)
	# Copying 1MB Bytes ...

	     894.454383 MB/Sec
	       3.844734 GB/Sec (with prefault)

	# Running mem/memset benchmark...
	Routine default (Default memset() provided by glibc)
	# Copying 1MB Bytes ...

	       1.220703 GB/Sec
	       9.042245 GB/Sec (with prefault)

Because misleadingly the 'all' refers to 'all sub-benchmarks', not 'all sub-benchmarks
and routines'.

Fix all this by making the memcpy/memset routine to default to 'all', which results in
all the benchmarks being run:

	triton:~> perf bench mem all
	# Running mem/memcpy benchmark...
	Routine default (Default memcpy() provided by glibc)
	# Copying 1MB Bytes ...

	       1.448906 GB/Sec
	       4.957170 GB/Sec (with prefault)
	Routine x86-64-unrolled (unrolled memcpy() in arch/x86/lib/memcpy_64.S)
	# Copying 1MB Bytes ...

	       1.614153 GB/Sec
	       4.379204 GB/Sec (with prefault)
	Routine x86-64-movsq (movsq-based memcpy() in arch/x86/lib/memcpy_64.S)
	# Copying 1MB Bytes ...

	       1.570036 GB/Sec
	       4.264465 GB/Sec (with prefault)
	Routine x86-64-movsb (movsb-based memcpy() in arch/x86/lib/memcpy_64.S)
	# Copying 1MB Bytes ...

	       1.788576 GB/Sec
	       6.554111 GB/Sec (with prefault)

	# Running mem/memset benchmark...
	Routine default (Default memset() provided by glibc)
	# Copying 1MB Bytes ...

	       2.082223 GB/Sec
	       9.126752 GB/Sec (with prefault)
	Routine x86-64-unrolled (unrolled memset() in arch/x86/lib/memset_64.S)
	# Copying 1MB Bytes ...

	       5.710892 GB/Sec
	       8.346688 GB/Sec (with prefault)
	Routine x86-64-stosq (movsq-based memset() in arch/x86/lib/memset_64.S)
	# Copying 1MB Bytes ...

	       9.765625 GB/Sec
	      12.520032 GB/Sec (with prefault)
	Routine x86-64-stosb (movsb-based memset() in arch/x86/lib/memset_64.S)
	# Copying 1MB Bytes ...

	       9.668936 GB/Sec
	      12.682630 GB/Sec (with prefault)

Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 tools/perf/bench/mem-memcpy.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
index 27606ff5c4f9..263f84171ae5 100644
--- a/tools/perf/bench/mem-memcpy.c
+++ b/tools/perf/bench/mem-memcpy.c
@@ -24,7 +24,7 @@
 #define K 1024
 
 static const char	*length_str	= "1MB";
-static const char	*routine	= "default";
+static const char	*routine	= "all";
 static int		iterations	= 1;
 static bool		use_cycle;
 static int		cycle_fd;
@@ -35,7 +35,7 @@ static const struct option options[] = {
 	OPT_STRING('l', "length", &length_str, "1MB",
 		    "Specify length of memory to copy. "
 		    "Available units: B, KB, MB, GB and TB (upper and lower)"),
-	OPT_STRING('r', "routine", &routine, "default",
+	OPT_STRING('r', "routine", &routine, "all",
 		    "Specify routine to copy, \"all\" runs all available routines"),
 	OPT_INTEGER('i', "iterations", &iterations,
 		    "repeat memcpy() invocation this number of times"),
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1250835 — Re: [PATCH 02/14] perf/bench: Default to all routines in 'perf bench mem'

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2015-10-19 17:30 +0200
SubjectRe: [PATCH 02/14] perf/bench: Default to all routines in 'perf bench mem'
Message-ID<qlkxQ-8qb-29@gated-at.bofh.it>
In reply to#1250433
On Mon, Oct 19, 2015 at 1:04 AM, Ingo Molnar <mingo@kernel.org> wrote:
>
>         triton:~> perf bench mem all
>         # Running mem/memcpy benchmark...
>         Routine default (Default memcpy() provided by glibc)
>                4.957170 GB/Sec (with prefault)
>         Routine x86-64-unrolled (unrolled memcpy() in arch/x86/lib/memcpy_64.S)
>                4.379204 GB/Sec (with prefault)
>         Routine x86-64-movsq (movsq-based memcpy() in arch/x86/lib/memcpy_64.S)
>                4.264465 GB/Sec (with prefault)
>         Routine x86-64-movsb (movsb-based memcpy() in arch/x86/lib/memcpy_64.S)
>                6.554111 GB/Sec (with prefault)

Is this skylake? And why are the numbers so low? Even on my laptop
(Haswell), I get ~21GB/s (when setting cpufreq to performance).

It's interesting that 'movsb' for you is so much better. It's been
promising before, and it *should* be able to do better than manual
copying, but it's not been that noticeable on the machines I've
tested. But I haven't ued Skylake or Broadwell yet.

cpufreq might be making a difference too. Maybe it's just ramping up
the CPU? Or is that really repeatable?

                     Linus
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1250960 — Re: [PATCH 02/14] perf/bench: Default to all routines in 'perf bench mem'

FromIngo Molnar <mingo@kernel.org>
Date2015-10-19 19:50 +0200
SubjectRe: [PATCH 02/14] perf/bench: Default to all routines in 'perf bench mem'
Message-ID<qlmJk-35z-17@gated-at.bofh.it>
In reply to#1250835
* Linus Torvalds <torvalds@linux-foundation.org> wrote:

> On Mon, Oct 19, 2015 at 1:04 AM, Ingo Molnar <mingo@kernel.org> wrote:
> >
> >         triton:~> perf bench mem all
> >         # Running mem/memcpy benchmark...
> >         Routine default (Default memcpy() provided by glibc)
> >                4.957170 GB/Sec (with prefault)
> >         Routine x86-64-unrolled (unrolled memcpy() in arch/x86/lib/memcpy_64.S)
> >                4.379204 GB/Sec (with prefault)
> >         Routine x86-64-movsq (movsq-based memcpy() in arch/x86/lib/memcpy_64.S)
> >                4.264465 GB/Sec (with prefault)
> >         Routine x86-64-movsb (movsb-based memcpy() in arch/x86/lib/memcpy_64.S)
> >                6.554111 GB/Sec (with prefault)
> 
> Is this skylake? And why are the numbers so low? Even on my laptop
> (Haswell), I get ~21GB/s (when setting cpufreq to performance).

No, this was on my desktop, which is a water cooled IvyBridge running at 3.6GHz:

 processor       : 11
 vendor_id       : GenuineIntel
 cpu family      : 6
 model           : 62
 model name      : Intel(R) Core(TM) i7-4960X CPU @ 3.60GHz
 stepping        : 4
 microcode       : 0x416
 cpu MHz         : 1303.031
 cache size      : 15360 KB

and I didn't really think about the validity of the numbers when I made the 
changelog, as I rarely benchmark on this box, due to it having various desktop 
loads running all the time.

AAs you noticed the results are highly variable with default settings:

  triton:~/tip> taskset 1 perf stat --null --repeat 10 perf bench mem memcpy -f x86-64-movsb 2>&1 | grep GB
       5.580357 GB/sec
       5.580357 GB/sec
      16.551907 GB/sec
      16.551907 GB/sec
      15.258789 GB/sec
      16.837284 GB/sec
      16.837284 GB/sec
      16.837284 GB/sec
      16.551907 GB/sec
      16.837284 GB/sec

They get more reliable with '-l 10000' (10,000 loops instead of the default 1):

  triton:~/tip> taskset 1 perf stat --null --repeat 10 perf bench mem memcpy -f x86-64-movsb -l 10000 2>&1 | grep GB
      15.483591 GB/sec
      16.975429 GB/sec
      17.088396 GB/sec
      20.920407 GB/sec
      21.346655 GB/sec
      21.322372 GB/sec
      21.338306 GB/sec
      21.342130 GB/sec
      21.339984 GB/sec
      21.373145 GB/sec

that's purely cached. Also note how after a few seconds it gets faster, due to 
cpufreq as you suspected.

So once I fix the frequency of all cores to the max, I get much more reliable 
results:

  triton:~/tip> taskset 1 perf stat --null --repeat 10 perf bench mem memcpy -f x86-64-movsb -l 10000 2>&1 | grep -E 'GB|elaps'
      21.356879 GB/sec
      21.378526 GB/sec
      21.351976 GB/sec
      21.375203 GB/sec
      21.369824 GB/sec
      21.353236 GB/sec
      21.283708 GB/sec
      21.380679 GB/sec
      21.347915 GB/sec
      21.378572 GB/sec
       0.459286278 seconds time elapsed                                          ( +-  0.04% )

I'll add a debug check to 'perf bench' to warn about systems that have variable 
cpufreq running - this is too easy a mistake to make :-/

So with the benchmark stabilized, I get the following results:

  triton:~/tip> taskset 1 perf bench mem memcpy -f all -l 10000
  # Running 'mem/memcpy' benchmark:
  # function 'default' (Default memcpy() provided by glibc)
  # Copying 1MB bytes ...
 
        18.356783 GB/sec
  # function 'x86-64-unrolled' (unrolled memcpy() in arch/x86/lib/memcpy_64.S)
  # Copying 1MB bytes ...
 
        16.294889 GB/sec
  # function 'x86-64-movsq' (movsq-based memcpy() in arch/x86/lib/memcpy_64.S)
  # Copying 1MB bytes ...
 
        15.760032 GB/sec
  # function 'x86-64-movsb' (movsb-based memcpy() in arch/x86/lib/memcpy_64.S)
  # Copying 1MB bytes ...

        21.145818 GB/sec

which matches your observations:

> It's interesting that 'movsb' for you is so much better. It's been
> promising before, and it *should* be able to do better than manual
> copying, but it's not been that noticeable on the machines I've
> tested. But I haven't ued Skylake or Broadwell yet.
> 
> cpufreq might be making a difference too. Maybe it's just ramping up
> the CPU? Or is that really repeatable?

So modulo the cpufreq multiplier it seems repeatable on this IB system - will try 
it on SkyLake as well.

Before relying on it I also wanted to implement the following 'perf bench' 
improvements:

 - make it more representative of kernel usage by benchmarking a list of
   characteristic lengths, not just the single stupid 1MB buffer. At smaller 
   buffer sizes I'd expect MOVSB to have even more of a fundamental advantage (due 
   to having all the differentiation in hardware) - but we don't know the
   latencies of those cases, some of which are in microcode I suspect.

 - measure aligned/unaligned buffer address and length effects as well

 - measure cache-cold numbers as well. This is pretty hard but not impossible.

With that we could start validating our fundamental memory op routines in 
user-space.

Thanks,

	Ingo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1251367 — [tip:perf/core] perf bench: Default to all routines in ' perf bench mem'

Fromtip-bot for Ingo Molnar <tipbot@zytor.com>
Date2015-10-20 09:50 +0200
Subject[tip:perf/core] perf bench: Default to all routines in ' perf bench mem'
Message-ID<qlzQd-5Bb-11@gated-at.bofh.it>
In reply to#1250433
Commit-ID:  276197415685e2a91ce367562800cf0f8fbe482c
Gitweb:     http://git.kernel.org/tip/276197415685e2a91ce367562800cf0f8fbe482c
Author:     Ingo Molnar <mingo@kernel.org>
AuthorDate: Mon, 19 Oct 2015 10:04:18 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 19 Oct 2015 15:05:34 -0300

perf bench: Default to all routines in 'perf bench mem'

So few people know that the --routine option to 'perf bench memcpy/memset'
exists, and would not know that it's capable of testing the kernel's
memcpy/memset implementations.

Furthermore, 'perf bench mem all' will not run all routines:

	vega:~> perf bench mem all
	# Running mem/memcpy benchmark...
	Routine default (Default memcpy() provided by glibc)
	# Copying 1MB Bytes ...

	     894.454383 MB/Sec
	       3.844734 GB/Sec (with prefault)

	# Running mem/memset benchmark...
	Routine default (Default memset() provided by glibc)
	# Copying 1MB Bytes ...

	       1.220703 GB/Sec
	       9.042245 GB/Sec (with prefault)

Because misleadingly the 'all' refers to 'all sub-benchmarks', not 'all
sub-benchmarks and routines'.

Fix all this by making the memcpy/memset routine to default to 'all',
which results in all the benchmarks being run:

	triton:~> perf bench mem all
	# Running mem/memcpy benchmark...
	Routine default (Default memcpy() provided by glibc)
	# Copying 1MB Bytes ...

	       1.448906 GB/Sec
	       4.957170 GB/Sec (with prefault)
	Routine x86-64-unrolled (unrolled memcpy() in arch/x86/lib/memcpy_64.S)
	# Copying 1MB Bytes ...

	       1.614153 GB/Sec
	       4.379204 GB/Sec (with prefault)
	Routine x86-64-movsq (movsq-based memcpy() in arch/x86/lib/memcpy_64.S)
	# Copying 1MB Bytes ...

	       1.570036 GB/Sec
	       4.264465 GB/Sec (with prefault)
	Routine x86-64-movsb (movsb-based memcpy() in arch/x86/lib/memcpy_64.S)
	# Copying 1MB Bytes ...

	       1.788576 GB/Sec
	       6.554111 GB/Sec (with prefault)

	# Running mem/memset benchmark...
	Routine default (Default memset() provided by glibc)
	# Copying 1MB Bytes ...

	       2.082223 GB/Sec
	       9.126752 GB/Sec (with prefault)
	Routine x86-64-unrolled (unrolled memset() in arch/x86/lib/memset_64.S)
	# Copying 1MB Bytes ...

	       5.710892 GB/Sec
	       8.346688 GB/Sec (with prefault)
	Routine x86-64-stosq (movsq-based memset() in arch/x86/lib/memset_64.S)
	# Copying 1MB Bytes ...

	       9.765625 GB/Sec
	      12.520032 GB/Sec (with prefault)
	Routine x86-64-stosb (movsb-based memset() in arch/x86/lib/memset_64.S)
	# Copying 1MB Bytes ...

	       9.668936 GB/Sec
	      12.682630 GB/Sec (with prefault)

Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1445241870-24854-3-git-send-email-mingo@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/bench/mem-memcpy.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
index 27606ff..263f841 100644
--- a/tools/perf/bench/mem-memcpy.c
+++ b/tools/perf/bench/mem-memcpy.c
@@ -24,7 +24,7 @@
 #define K 1024
 
 static const char	*length_str	= "1MB";
-static const char	*routine	= "default";
+static const char	*routine	= "all";
 static int		iterations	= 1;
 static bool		use_cycle;
 static int		cycle_fd;
@@ -35,7 +35,7 @@ static const struct option options[] = {
 	OPT_STRING('l', "length", &length_str, "1MB",
 		    "Specify length of memory to copy. "
 		    "Available units: B, KB, MB, GB and TB (upper and lower)"),
-	OPT_STRING('r', "routine", &routine, "default",
+	OPT_STRING('r', "routine", &routine, "all",
 		    "Specify routine to copy, \"all\" runs all available routines"),
 	OPT_INTEGER('i', "iterations", &iterations,
 		    "repeat memcpy() invocation this number of times"),
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1250434 — [PATCH 06/14] perf/bench: List output formatting options on 'perf bench -h'

FromIngo Molnar <mingo@kernel.org>
Date2015-10-19 10:20 +0200
Subject[PATCH 06/14] perf/bench: List output formatting options on 'perf bench -h'
Message-ID<qldPH-74y-9@gated-at.bofh.it>
In reply to#1250418
So 'perf bench -h' is not very helpful when printing the help line
about the output formatting options:

    -f, --format <default>
                              Specify format style

There are two output format styles, 'default' and 'simple', so improve
the help text to:

    -f, --format <default|simple>
                              Specify the output formatting style

Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 tools/perf/bench/mem-functions.c |   4 +-
 tools/perf/bench/mem-memcpy.c    | 420 -----------------------------------------------------------
 tools/perf/builtin-bench.c       |   2 +-
 3 files changed, 3 insertions(+), 423 deletions(-)

diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c
index 33de5d57a163..d822ee0c6003 100644
--- a/tools/perf/bench/mem-functions.c
+++ b/tools/perf/bench/mem-functions.c
@@ -273,7 +273,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len)
 	return (double)(((double)len * iterations) / timeval2double(&tv_diff));
 }
 
-int bench_mem_memcpy(int argc, const char **argv, const char *prefix __unused)
+int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unused)
 {
 	struct bench_mem_info info = {
 		.routines		= memcpy_routines,
@@ -361,7 +361,7 @@ static const struct routine memset_routines[] = {
 	{ NULL, }
 };
 
-int bench_mem_memset(int argc, const char **argv, const char *prefix __unused)
+int bench_mem_memset(int argc, const char **argv, const char *prefix __maybe_unused)
 {
 	struct bench_mem_info info = {
 		.routines		= memset_routines,
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
deleted file mode 100644
index 7acb9b83382c..000000000000
--- a/tools/perf/bench/mem-memcpy.c
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * mem-memcpy.c
- *
- * Simple memcpy() and memset() benchmarks
- *
- * Written by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
- */
-
-#include "../perf.h"
-#include "../util/util.h"
-#include "../util/parse-options.h"
-#include "../util/header.h"
-#include "../util/cloexec.h"
-#include "bench.h"
-#include "mem-memcpy-arch.h"
-#include "mem-memset-arch.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <errno.h>
-
-#define K 1024
-
-static const char	*length_str	= "1MB";
-static const char	*routine	= "all";
-static int		iterations	= 1;
-static bool		use_cycle;
-static int		cycle_fd;
-static bool		only_prefault;
-static bool		no_prefault;
-
-static const struct option options[] = {
-	OPT_STRING('l', "length", &length_str, "1MB",
-		    "Specify length of memory to copy. "
-		    "Available units: B, KB, MB, GB and TB (upper and lower)"),
-	OPT_STRING('r', "routine", &routine, "all",
-		    "Specify routine to copy, \"all\" runs all available routines"),
-	OPT_INTEGER('i', "iterations", &iterations,
-		    "repeat memcpy() invocation this number of times"),
-	OPT_BOOLEAN('c', "cycle", &use_cycle,
-		    "Use cycles event instead of gettimeofday() for measuring"),
-	OPT_BOOLEAN('o', "only-prefault", &only_prefault,
-		    "Show only the result with page faults before memcpy()"),
-	OPT_BOOLEAN('n', "no-prefault", &no_prefault,
-		    "Show only the result without page faults before memcpy()"),
-	OPT_END()
-};
-
-typedef void *(*memcpy_t)(void *, const void *, size_t);
-typedef void *(*memset_t)(void *, int, size_t);
-
-struct routine {
-	const char *name;
-	const char *desc;
-	union {
-		memcpy_t memcpy;
-		memset_t memset;
-	} fn;
-};
-
-struct routine memcpy_routines[] = {
-	{ .name		= "default",
-	  .desc		= "Default memcpy() provided by glibc",
-	  .fn.memcpy	= memcpy },
-
-#ifdef HAVE_ARCH_X86_64_SUPPORT
-# define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn},
-# include "mem-memcpy-x86-64-asm-def.h"
-# undef MEMCPY_FN
-#endif
-
-	{ NULL, }
-};
-
-static const char * const bench_mem_memcpy_usage[] = {
-	"perf bench mem memcpy <options>",
-	NULL
-};
-
-static struct perf_event_attr cycle_attr = {
-	.type		= PERF_TYPE_HARDWARE,
-	.config		= PERF_COUNT_HW_CPU_CYCLES
-};
-
-static void init_cycle(void)
-{
-	cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, perf_event_open_cloexec_flag());
-
-	if (cycle_fd < 0 && errno == ENOSYS)
-		die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
-	else
-		BUG_ON(cycle_fd < 0);
-}
-
-static u64 get_cycle(void)
-{
-	int ret;
-	u64 clk;
-
-	ret = read(cycle_fd, &clk, sizeof(u64));
-	BUG_ON(ret != sizeof(u64));
-
-	return clk;
-}
-
-static double timeval2double(struct timeval *ts)
-{
-	return (double)ts->tv_sec + (double)ts->tv_usec / (double)1000000;
-}
-
-#define print_bps(x) do {					\
-		if (x < K)					\
-			printf(" %14lf B/Sec", x);		\
-		else if (x < K * K)				\
-			printf(" %14lfd KB/Sec", x / K);	\
-		else if (x < K * K * K)				\
-			printf(" %14lf MB/Sec", x / K / K);	\
-		else						\
-			printf(" %14lf GB/Sec", x / K / K / K); \
-	} while (0)
-
-struct bench_mem_info {
-	const struct routine *routines;
-	u64 (*do_cycle)(const struct routine *r, size_t len, bool prefault);
-	double (*do_gettimeofday)(const struct routine *r, size_t len, bool prefault);
-	const char *const *usage;
-};
-
-static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t len, double totallen)
-{
-	const struct routine *r = &info->routines[r_idx];
-	double result_bps[2];
-	u64 result_cycle[2];
-	int prefault = no_prefault ? 0 : 1;
-
-	result_cycle[0] = result_cycle[1] = 0ULL;
-	result_bps[0] = result_bps[1] = 0.0;
-
-	printf("Routine %s (%s)\n", r->name, r->desc);
-
-	if (bench_format == BENCH_FORMAT_DEFAULT)
-		printf("# Copying %s Bytes ...\n\n", length_str);
-
-	if (!only_prefault && prefault) {
-		/* Show both results: */
-		if (use_cycle) {
-			result_cycle[0] = info->do_cycle(r, len, false);
-			result_cycle[1] = info->do_cycle(r, len, true);
-		} else {
-			result_bps[0]   = info->do_gettimeofday(r, len, false);
-			result_bps[1]   = info->do_gettimeofday(r, len, true);
-		}
-	} else {
-		if (use_cycle)
-			result_cycle[prefault] = info->do_cycle(r, len, only_prefault);
-		else
-			result_bps[prefault] = info->do_gettimeofday(r, len, only_prefault);
-	}
-
-	switch (bench_format) {
-	case BENCH_FORMAT_DEFAULT:
-		if (!only_prefault && prefault) {
-			if (use_cycle) {
-				printf(" %14lf Cycle/Byte\n",
-					(double)result_cycle[0]
-					/ totallen);
-				printf(" %14lf Cycle/Byte (with prefault)\n",
-					(double)result_cycle[1]
-					/ totallen);
-			} else {
-				print_bps(result_bps[0]);
-				printf("\n");
-				print_bps(result_bps[1]);
-				printf(" (with prefault)\n");
-			}
-		} else {
-			if (use_cycle) {
-				printf(" %14lf Cycle/Byte",
-					(double)result_cycle[prefault]
-					/ totallen);
-			} else
-				print_bps(result_bps[prefault]);
-
-			printf("%s\n", only_prefault ? " (with prefault)" : "");
-		}
-		break;
-	case BENCH_FORMAT_SIMPLE:
-		if (!only_prefault && prefault) {
-			if (use_cycle) {
-				printf("%lf %lf\n",
-					(double)result_cycle[0] / totallen,
-					(double)result_cycle[1] / totallen);
-			} else {
-				printf("%lf %lf\n",
-					result_bps[0], result_bps[1]);
-			}
-		} else {
-			if (use_cycle) {
-				printf("%lf\n", (double)result_cycle[prefault]
-					/ totallen);
-			} else
-				printf("%lf\n", result_bps[prefault]);
-		}
-		break;
-	default:
-		/* Reaching this means there's some disaster: */
-		die("unknown format: %d\n", bench_format);
-		break;
-	}
-}
-
-static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *info)
-{
-	int i;
-	size_t len;
-	double totallen;
-
-	argc = parse_options(argc, argv, options, info->usage, 0);
-
-	if (no_prefault && only_prefault) {
-		fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n");
-		return 1;
-	}
-
-	if (use_cycle)
-		init_cycle();
-
-	len = (size_t)perf_atoll((char *)length_str);
-	totallen = (double)len * iterations;
-
-	if ((s64)len <= 0) {
-		fprintf(stderr, "Invalid length:%s\n", length_str);
-		return 1;
-	}
-
-	/* Same as without specifying either of prefault and no-prefault: */
-	if (only_prefault && no_prefault)
-		only_prefault = no_prefault = false;
-
-	if (!strncmp(routine, "all", 3)) {
-		for (i = 0; info->routines[i].name; i++)
-			__bench_mem_routine(info, i, len, totallen);
-		return 0;
-	}
-
-	for (i = 0; info->routines[i].name; i++) {
-		if (!strcmp(info->routines[i].name, routine))
-			break;
-	}
-	if (!info->routines[i].name) {
-		printf("Unknown routine:%s\n", routine);
-		printf("Available routines...\n");
-		for (i = 0; info->routines[i].name; i++) {
-			printf("\t%s ... %s\n",
-			       info->routines[i].name, info->routines[i].desc);
-		}
-		return 1;
-	}
-
-	__bench_mem_routine(info, i, len, totallen);
-
-	return 0;
-}
-
-static void memcpy_alloc_mem(void **dst, void **src, size_t length)
-{
-	*dst = zalloc(length);
-	if (!*dst)
-		die("memory allocation failed - maybe length is too large?\n");
-
-	*src = zalloc(length);
-	if (!*src)
-		die("memory allocation failed - maybe length is too large?\n");
-
-	/* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */
-	memset(*src, 0, length);
-}
-
-static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault)
-{
-	u64 cycle_start = 0ULL, cycle_end = 0ULL;
-	void *src = NULL, *dst = NULL;
-	memcpy_t fn = r->fn.memcpy;
-	int i;
-
-	memcpy_alloc_mem(&dst, &src, len);
-
-	if (prefault)
-		fn(dst, src, len);
-
-	cycle_start = get_cycle();
-	for (i = 0; i < iterations; ++i)
-		fn(dst, src, len);
-	cycle_end = get_cycle();
-
-	free(src);
-	free(dst);
-	return cycle_end - cycle_start;
-}
-
-static double do_memcpy_gettimeofday(const struct routine *r, size_t len, bool prefault)
-{
-	struct timeval tv_start, tv_end, tv_diff;
-	memcpy_t fn = r->fn.memcpy;
-	void *src = NULL, *dst = NULL;
-	int i;
-
-	memcpy_alloc_mem(&dst, &src, len);
-
-	if (prefault)
-		fn(dst, src, len);
-
-	BUG_ON(gettimeofday(&tv_start, NULL));
-	for (i = 0; i < iterations; ++i)
-		fn(dst, src, len);
-	BUG_ON(gettimeofday(&tv_end, NULL));
-
-	timersub(&tv_end, &tv_start, &tv_diff);
-
-	free(src);
-	free(dst);
-	return (double)(((double)len * iterations) / timeval2double(&tv_diff));
-}
-
-int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unused)
-{
-	struct bench_mem_info info = {
-		.routines		= memcpy_routines,
-		.do_cycle		= do_memcpy_cycle,
-		.do_gettimeofday	= do_memcpy_gettimeofday,
-		.usage			= bench_mem_memcpy_usage,
-	};
-
-	return bench_mem_common(argc, argv, &info);
-}
-
-static void memset_alloc_mem(void **dst, size_t length)
-{
-	*dst = zalloc(length);
-	if (!*dst)
-		die("memory allocation failed - maybe length is too large?\n");
-}
-
-static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault)
-{
-	u64 cycle_start = 0ULL, cycle_end = 0ULL;
-	memset_t fn = r->fn.memset;
-	void *dst = NULL;
-	int i;
-
-	memset_alloc_mem(&dst, len);
-
-	if (prefault)
-		fn(dst, -1, len);
-
-	cycle_start = get_cycle();
-	for (i = 0; i < iterations; ++i)
-		fn(dst, i, len);
-	cycle_end = get_cycle();
-
-	free(dst);
-	return cycle_end - cycle_start;
-}
-
-static double do_memset_gettimeofday(const struct routine *r, size_t len,
-				     bool prefault)
-{
-	struct timeval tv_start, tv_end, tv_diff;
-	memset_t fn = r->fn.memset;
-	void *dst = NULL;
-	int i;
-
-	memset_alloc_mem(&dst, len);
-
-	if (prefault)
-		fn(dst, -1, len);
-
-	BUG_ON(gettimeofday(&tv_start, NULL));
-	for (i = 0; i < iterations; ++i)
-		fn(dst, i, len);
-	BUG_ON(gettimeofday(&tv_end, NULL));
-
-	timersub(&tv_end, &tv_start, &tv_diff);
-
-	free(dst);
-	return (double)(((double)len * iterations) / timeval2double(&tv_diff));
-}
-
-static const char * const bench_mem_memset_usage[] = {
-	"perf bench mem memset <options>",
-	NULL
-};
-
-static const struct routine memset_routines[] = {
-	{ .name		= "default",
-	  .desc		= "Default memset() provided by glibc",
-	  .fn.memset	= memset },
-
-#ifdef HAVE_ARCH_X86_64_SUPPORT
-# define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn },
-# include "mem-memset-x86-64-asm-def.h"
-# undef MEMSET_FN
-#endif
-
-	{ NULL, }
-};
-
-int bench_mem_memset(int argc, const char **argv, const char *prefix __maybe_unused)
-{
-	struct bench_mem_info info = {
-		.routines		= memset_routines,
-		.do_cycle		= do_memset_cycle,
-		.do_gettimeofday	= do_memset_gettimeofday,
-		.usage			= bench_mem_memset_usage,
-	};
-
-	return bench_mem_common(argc, argv, &info);
-}
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
index f67934d46d40..1b585213ba5a 100644
--- a/tools/perf/builtin-bench.c
+++ b/tools/perf/builtin-bench.c
@@ -110,7 +110,7 @@ int bench_format = BENCH_FORMAT_DEFAULT;
 unsigned int bench_repeat = 10; /* default number of times to repeat the run */
 
 static const struct option bench_options[] = {
-	OPT_STRING('f', "format", &bench_format_str, "default", "Specify format style"),
+	OPT_STRING('f', "format", &bench_format_str, "default|simple", "Specify the output formatting style"),
 	OPT_UINTEGER('r', "repeat",  &bench_repeat,   "Specify amount of times to repeat the run"),
 	OPT_END()
 };
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1250701 — Re: [PATCH 06/14] perf/bench: List output formatting options on 'perf bench -h'

FromDavid Ahern <dsahern@gmail.com>
Date2015-10-19 15:30 +0200
SubjectRe: [PATCH 06/14] perf/bench: List output formatting options on 'perf bench -h'
Message-ID<qliFL-5Ez-69@gated-at.bofh.it>
In reply to#1250434
On 10/19/15 2:04 AM, Ingo Molnar wrote:
> diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c
> index 33de5d57a163..d822ee0c6003 100644
> --- a/tools/perf/bench/mem-functions.c
> +++ b/tools/perf/bench/mem-functions.c
> @@ -273,7 +273,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len)
>   	return (double)(((double)len * iterations) / timeval2double(&tv_diff));
>   }
>
> -int bench_mem_memcpy(int argc, const char **argv, const char *prefix __unused)
> +int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unused)
>   {
>   	struct bench_mem_info info = {
>   		.routines		= memcpy_routines,
> @@ -361,7 +361,7 @@ static const struct routine memset_routines[] = {
>   	{ NULL, }
>   };
>
> -int bench_mem_memset(int argc, const char **argv, const char *prefix __unused)
> +int bench_mem_memset(int argc, const char **argv, const char *prefix __maybe_unused)
>   {
>   	struct bench_mem_info info = {
>   		.routines		= memset_routines,
> diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
> deleted file mode 100644
> index 7acb9b83382c..000000000000
> --- a/tools/perf/bench/mem-memcpy.c
> +++ /dev/null

All of this seems like leftovers from previous patches.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1251012 — Re: [PATCH 06/14] perf/bench: List output formatting options on 'perf bench -h'

FromArnaldo Carvalho de Melo <acme@redhat.com>
Date2015-10-19 21:00 +0200
SubjectRe: [PATCH 06/14] perf/bench: List output formatting options on 'perf bench -h'
Message-ID<qlnP5-4FP-29@gated-at.bofh.it>
In reply to#1250701
Em Mon, Oct 19, 2015 at 07:28:56AM -0600, David Ahern escreveu:
> On 10/19/15 2:04 AM, Ingo Molnar wrote:
> >diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c
> >index 33de5d57a163..d822ee0c6003 100644
> >--- a/tools/perf/bench/mem-functions.c
> >+++ b/tools/perf/bench/mem-functions.c
> >@@ -273,7 +273,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len)
> >  	return (double)(((double)len * iterations) / timeval2double(&tv_diff));
> >  }
> >
> >-int bench_mem_memcpy(int argc, const char **argv, const char *prefix __unused)
> >+int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unused)
> >  {
> >  	struct bench_mem_info info = {
> >  		.routines		= memcpy_routines,
> >@@ -361,7 +361,7 @@ static const struct routine memset_routines[] = {
> >  	{ NULL, }
> >  };
> >
> >-int bench_mem_memset(int argc, const char **argv, const char *prefix __unused)
> >+int bench_mem_memset(int argc, const char **argv, const char *prefix __maybe_unused)
> >  {
> >  	struct bench_mem_info info = {
> >  		.routines		= memset_routines,
> >diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
> >deleted file mode 100644
> >index 7acb9b83382c..000000000000
> >--- a/tools/perf/bench/mem-memcpy.c
> >+++ /dev/null
> 
> All of this seems like leftovers from previous patches.

Right, I fixed this one at the rename point, 4/5 IIRc
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1251393 — [tip:perf/core] perf bench: List output formatting options on ' perf bench -h'

Fromtip-bot for Ingo Molnar <tipbot@zytor.com>
Date2015-10-20 09:50 +0200
Subject[tip:perf/core] perf bench: List output formatting options on ' perf bench -h'
Message-ID<qlzQg-5Bb-73@gated-at.bofh.it>
In reply to#1250434
Commit-ID:  7a46a8fd13bd60584687f417cd35935965f29ae2
Gitweb:     http://git.kernel.org/tip/7a46a8fd13bd60584687f417cd35935965f29ae2
Author:     Ingo Molnar <mingo@kernel.org>
AuthorDate: Mon, 19 Oct 2015 10:04:22 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 19 Oct 2015 16:03:53 -0300

perf bench: List output formatting options on 'perf bench -h'

So 'perf bench -h' is not very helpful when printing the help line
about the output formatting options:

    -f, --format <default>
                              Specify format style

There are two output format styles, 'default' and 'simple', so improve
the help text to:

    -f, --format <default|simple>
                              Specify the output formatting style

Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1445241870-24854-7-git-send-email-mingo@kernel.org
[ Removed leftovers from the mem-functions.c rename ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-bench.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
index f67934d..1b58521 100644
--- a/tools/perf/builtin-bench.c
+++ b/tools/perf/builtin-bench.c
@@ -110,7 +110,7 @@ int bench_format = BENCH_FORMAT_DEFAULT;
 unsigned int bench_repeat = 10; /* default number of times to repeat the run */
 
 static const struct option bench_options[] = {
-	OPT_STRING('f', "format", &bench_format_str, "default", "Specify format style"),
+	OPT_STRING('f', "format", &bench_format_str, "default|simple", "Specify the output formatting style"),
 	OPT_UINTEGER('r', "repeat",  &bench_repeat,   "Specify amount of times to repeat the run"),
 	OPT_END()
 };
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1250437 — [PATCH 05/14] perf/bench: Remove the prefaulting complication from 'perf bench mem mem*'

FromIngo Molnar <mingo@kernel.org>
Date2015-10-19 10:20 +0200
Subject[PATCH 05/14] perf/bench: Remove the prefaulting complication from 'perf bench mem mem*'
Message-ID<qldPI-74y-15@gated-at.bofh.it>
In reply to#1250418
So 'perf bench mem memcpy/memset' has elaborate code to measure
memcpy()/memset() performance both with freshly allocated buffers
(which includes initial page fault overhead) and with preallocated
buffers.

But the thing is, the resulting bandwidth results are mostly
meaningless, because page faults dominate so much of the cost.

It might make sense to measure cache cold vs. cache hot performance,
but the code does not do this.

So remove this complication, and always prefault the ranges before
using them.

Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 tools/perf/bench/mem-functions.c | 146 ++++++++++++++++++++---------------------------------------
 1 file changed, 50 insertions(+), 96 deletions(-)

diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c
index 8f91c2e6b459..33de5d57a163 100644
--- a/tools/perf/bench/mem-functions.c
+++ b/tools/perf/bench/mem-functions.c
@@ -28,8 +28,6 @@ static const char	*routine	= "all";
 static int		iterations	= 1;
 static bool		use_cycle;
 static int		cycle_fd;
-static bool		only_prefault;
-static bool		no_prefault;
 
 static const struct option options[] = {
 	OPT_STRING('l', "length", &length_str, "1MB",
@@ -41,10 +39,6 @@ static const struct option options[] = {
 		    "repeat memcpy() invocation this number of times"),
 	OPT_BOOLEAN('c', "cycle", &use_cycle,
 		    "Use cycles event instead of gettimeofday() for measuring"),
-	OPT_BOOLEAN('o', "only-prefault", &only_prefault,
-		    "Show only the result with page faults before memcpy()"),
-	OPT_BOOLEAN('n', "no-prefault", &no_prefault,
-		    "Show only the result without page faults before memcpy()"),
 	OPT_END()
 };
 
@@ -110,103 +104,60 @@ static double timeval2double(struct timeval *ts)
 	return (double)ts->tv_sec + (double)ts->tv_usec / (double)1000000;
 }
 
-#define print_bps(x) do {					\
-		if (x < K)					\
-			printf(" %14lf B/Sec", x);		\
-		else if (x < K * K)				\
-			printf(" %14lfd KB/Sec", x / K);	\
-		else if (x < K * K * K)				\
-			printf(" %14lf MB/Sec", x / K / K);	\
-		else						\
-			printf(" %14lf GB/Sec", x / K / K / K); \
+#define print_bps(x) do {						\
+		if (x < K)						\
+			printf(" %14lf B/Sec\n", x);			\
+		else if (x < K * K)					\
+			printf(" %14lfd KB/Sec\n", x / K);		\
+		else if (x < K * K * K)					\
+			printf(" %14lf MB/Sec\n", x / K / K);		\
+		else							\
+			printf(" %14lf GB/Sec\n", x / K / K / K);	\
 	} while (0)
 
 struct bench_mem_info {
 	const struct routine *routines;
-	u64 (*do_cycle)(const struct routine *r, size_t len, bool prefault);
-	double (*do_gettimeofday)(const struct routine *r, size_t len, bool prefault);
+	u64 (*do_cycle)(const struct routine *r, size_t len);
+	double (*do_gettimeofday)(const struct routine *r, size_t len);
 	const char *const *usage;
 };
 
 static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t len, double totallen)
 {
 	const struct routine *r = &info->routines[r_idx];
-	double result_bps[2];
-	u64 result_cycle[2];
-	int prefault = no_prefault ? 0 : 1;
-
-	result_cycle[0] = result_cycle[1] = 0ULL;
-	result_bps[0] = result_bps[1] = 0.0;
+	double result_bps = 0.0;
+	u64 result_cycle = 0;
 
 	printf("Routine %s (%s)\n", r->name, r->desc);
 
 	if (bench_format == BENCH_FORMAT_DEFAULT)
 		printf("# Copying %s Bytes ...\n\n", length_str);
 
-	if (!only_prefault && prefault) {
-		/* Show both results: */
-		if (use_cycle) {
-			result_cycle[0] = info->do_cycle(r, len, false);
-			result_cycle[1] = info->do_cycle(r, len, true);
-		} else {
-			result_bps[0]   = info->do_gettimeofday(r, len, false);
-			result_bps[1]   = info->do_gettimeofday(r, len, true);
-		}
+	if (use_cycle) {
+		result_cycle = info->do_cycle(r, len);
 	} else {
-		if (use_cycle)
-			result_cycle[prefault] = info->do_cycle(r, len, only_prefault);
-		else
-			result_bps[prefault] = info->do_gettimeofday(r, len, only_prefault);
+		result_bps = info->do_gettimeofday(r, len);
 	}
 
 	switch (bench_format) {
 	case BENCH_FORMAT_DEFAULT:
-		if (!only_prefault && prefault) {
-			if (use_cycle) {
-				printf(" %14lf Cycle/Byte\n",
-					(double)result_cycle[0]
-					/ totallen);
-				printf(" %14lf Cycle/Byte (with prefault)\n",
-					(double)result_cycle[1]
-					/ totallen);
-			} else {
-				print_bps(result_bps[0]);
-				printf("\n");
-				print_bps(result_bps[1]);
-				printf(" (with prefault)\n");
-			}
+		if (use_cycle) {
+			printf(" %14lf Cycle/Byte\n", (double)result_cycle/totallen);
 		} else {
-			if (use_cycle) {
-				printf(" %14lf Cycle/Byte",
-					(double)result_cycle[prefault]
-					/ totallen);
-			} else
-				print_bps(result_bps[prefault]);
-
-			printf("%s\n", only_prefault ? " (with prefault)" : "");
+			print_bps(result_bps);
 		}
 		break;
+
 	case BENCH_FORMAT_SIMPLE:
-		if (!only_prefault && prefault) {
-			if (use_cycle) {
-				printf("%lf %lf\n",
-					(double)result_cycle[0] / totallen,
-					(double)result_cycle[1] / totallen);
-			} else {
-				printf("%lf %lf\n",
-					result_bps[0], result_bps[1]);
-			}
+		if (use_cycle) {
+			printf("%lf\n", (double)result_cycle/totallen);
 		} else {
-			if (use_cycle) {
-				printf("%lf\n", (double)result_cycle[prefault]
-					/ totallen);
-			} else
-				printf("%lf\n", result_bps[prefault]);
+			printf("%lf\n", result_bps);
 		}
 		break;
+
 	default:
-		/* Reaching this means there's some disaster: */
-		die("unknown format: %d\n", bench_format);
+		BUG_ON(1);
 		break;
 	}
 }
@@ -219,11 +170,6 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *
 
 	argc = parse_options(argc, argv, options, info->usage, 0);
 
-	if (no_prefault && only_prefault) {
-		fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n");
-		return 1;
-	}
-
 	if (use_cycle)
 		init_cycle();
 
@@ -235,10 +181,6 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *
 		return 1;
 	}
 
-	/* Same as without specifying either of prefault and no-prefault: */
-	if (only_prefault && no_prefault)
-		only_prefault = no_prefault = false;
-
 	if (!strncmp(routine, "all", 3)) {
 		for (i = 0; info->routines[i].name; i++)
 			__bench_mem_routine(info, i, len, totallen);
@@ -278,7 +220,7 @@ static void memcpy_alloc_mem(void **dst, void **src, size_t length)
 	memset(*src, 0, length);
 }
 
-static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault)
+static u64 do_memcpy_cycle(const struct routine *r, size_t len)
 {
 	u64 cycle_start = 0ULL, cycle_end = 0ULL;
 	void *src = NULL, *dst = NULL;
@@ -287,8 +229,11 @@ static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault)
 
 	memcpy_alloc_mem(&dst, &src, len);
 
-	if (prefault)
-		fn(dst, src, len);
+	/*
+	 * We prefault the freshly allocated memory range here,
+	 * to not measure page fault overhead:
+	 */
+	fn(dst, src, len);
 
 	cycle_start = get_cycle();
 	for (i = 0; i < iterations; ++i)
@@ -300,7 +245,7 @@ static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault)
 	return cycle_end - cycle_start;
 }
 
-static double do_memcpy_gettimeofday(const struct routine *r, size_t len, bool prefault)
+static double do_memcpy_gettimeofday(const struct routine *r, size_t len)
 {
 	struct timeval tv_start, tv_end, tv_diff;
 	memcpy_t fn = r->fn.memcpy;
@@ -309,8 +254,11 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len, bool p
 
 	memcpy_alloc_mem(&dst, &src, len);
 
-	if (prefault)
-		fn(dst, src, len);
+	/*
+	 * We prefault the freshly allocated memory range here,
+	 * to not measure page fault overhead:
+	 */
+	fn(dst, src, len);
 
 	BUG_ON(gettimeofday(&tv_start, NULL));
 	for (i = 0; i < iterations; ++i)
@@ -321,6 +269,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len, bool p
 
 	free(src);
 	free(dst);
+
 	return (double)(((double)len * iterations) / timeval2double(&tv_diff));
 }
 
@@ -343,7 +292,7 @@ static void memset_alloc_mem(void **dst, size_t length)
 		die("memory allocation failed - maybe length is too large?\n");
 }
 
-static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault)
+static u64 do_memset_cycle(const struct routine *r, size_t len)
 {
 	u64 cycle_start = 0ULL, cycle_end = 0ULL;
 	memset_t fn = r->fn.memset;
@@ -352,8 +301,11 @@ static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault)
 
 	memset_alloc_mem(&dst, len);
 
-	if (prefault)
-		fn(dst, -1, len);
+	/*
+	 * We prefault the freshly allocated memory range here,
+	 * to not measure page fault overhead:
+	 */
+	fn(dst, -1, len);
 
 	cycle_start = get_cycle();
 	for (i = 0; i < iterations; ++i)
@@ -364,8 +316,7 @@ static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault)
 	return cycle_end - cycle_start;
 }
 
-static double do_memset_gettimeofday(const struct routine *r, size_t len,
-				     bool prefault)
+static double do_memset_gettimeofday(const struct routine *r, size_t len)
 {
 	struct timeval tv_start, tv_end, tv_diff;
 	memset_t fn = r->fn.memset;
@@ -374,8 +325,11 @@ static double do_memset_gettimeofday(const struct routine *r, size_t len,
 
 	memset_alloc_mem(&dst, len);
 
-	if (prefault)
-		fn(dst, -1, len);
+	/*
+	 * We prefault the freshly allocated memory range here,
+	 * to not measure page fault overhead:
+	 */
+	fn(dst, -1, len);
 
 	BUG_ON(gettimeofday(&tv_start, NULL));
 	for (i = 0; i < iterations; ++i)
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1251368 — [tip:perf/core] perf bench: Remove the prefaulting complication from 'perf bench mem mem*'

Fromtip-bot for Ingo Molnar <tipbot@zytor.com>
Date2015-10-20 09:50 +0200
Subject[tip:perf/core] perf bench: Remove the prefaulting complication from 'perf bench mem mem*'
Message-ID<qlzQe-5Bb-17@gated-at.bofh.it>
In reply to#1250437
Commit-ID:  6db175c7333e22ee818373cbea067e3eaa0236f7
Gitweb:     http://git.kernel.org/tip/6db175c7333e22ee818373cbea067e3eaa0236f7
Author:     Ingo Molnar <mingo@kernel.org>
AuthorDate: Mon, 19 Oct 2015 10:04:21 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 19 Oct 2015 16:03:31 -0300

perf bench: Remove the prefaulting complication from 'perf bench mem mem*'

So 'perf bench mem memcpy/memset' has elaborate code to measure
memcpy()/memset() performance both with freshly allocated buffers (which
includes initial page fault overhead) and with preallocated buffers.

But the thing is, the resulting bandwidth results are mostly
meaningless, because page faults dominate so much of the cost.

It might make sense to measure cache cold vs. cache hot performance, but
the code does not do this.

So remove this complication, and always prefault the ranges before using
them.

Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1445241870-24854-6-git-send-email-mingo@kernel.org
[ Remove --no-prefault, --only-prefault from docs, noticed by David Ahern ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-bench.txt |  16 ----
 tools/perf/bench/mem-functions.c        | 146 +++++++++++---------------------
 2 files changed, 50 insertions(+), 112 deletions(-)

diff --git a/tools/perf/Documentation/perf-bench.txt b/tools/perf/Documentation/perf-bench.txt
index ab632d9..9cb60ab 100644
--- a/tools/perf/Documentation/perf-bench.txt
+++ b/tools/perf/Documentation/perf-bench.txt
@@ -157,14 +157,6 @@ Repeat memcpy invocation this number of times.
 --cycle::
 Use perf's cpu-cycles event instead of gettimeofday syscall.
 
--o::
---only-prefault::
-Show only the result with page faults before memcpy.
-
--n::
---no-prefault::
-Show only the result without page faults before memcpy.
-
 *memset*::
 Suite for evaluating performance of simple memory set in various ways.
 
@@ -189,14 +181,6 @@ Repeat memset invocation this number of times.
 --cycle::
 Use perf's cpu-cycles event instead of gettimeofday syscall.
 
--o::
---only-prefault::
-Show only the result with page faults before memset.
-
--n::
---no-prefault::
-Show only the result without page faults before memset.
-
 SUITES FOR 'numa'
 ~~~~~~~~~~~~~~~~~
 *mem*::
diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c
index 7acb9b8..9c18a4b 100644
--- a/tools/perf/bench/mem-functions.c
+++ b/tools/perf/bench/mem-functions.c
@@ -28,8 +28,6 @@ static const char	*routine	= "all";
 static int		iterations	= 1;
 static bool		use_cycle;
 static int		cycle_fd;
-static bool		only_prefault;
-static bool		no_prefault;
 
 static const struct option options[] = {
 	OPT_STRING('l', "length", &length_str, "1MB",
@@ -41,10 +39,6 @@ static const struct option options[] = {
 		    "repeat memcpy() invocation this number of times"),
 	OPT_BOOLEAN('c', "cycle", &use_cycle,
 		    "Use cycles event instead of gettimeofday() for measuring"),
-	OPT_BOOLEAN('o', "only-prefault", &only_prefault,
-		    "Show only the result with page faults before memcpy()"),
-	OPT_BOOLEAN('n', "no-prefault", &no_prefault,
-		    "Show only the result without page faults before memcpy()"),
 	OPT_END()
 };
 
@@ -110,103 +104,60 @@ static double timeval2double(struct timeval *ts)
 	return (double)ts->tv_sec + (double)ts->tv_usec / (double)1000000;
 }
 
-#define print_bps(x) do {					\
-		if (x < K)					\
-			printf(" %14lf B/Sec", x);		\
-		else if (x < K * K)				\
-			printf(" %14lfd KB/Sec", x / K);	\
-		else if (x < K * K * K)				\
-			printf(" %14lf MB/Sec", x / K / K);	\
-		else						\
-			printf(" %14lf GB/Sec", x / K / K / K); \
+#define print_bps(x) do {						\
+		if (x < K)						\
+			printf(" %14lf B/Sec\n", x);			\
+		else if (x < K * K)					\
+			printf(" %14lfd KB/Sec\n", x / K);		\
+		else if (x < K * K * K)					\
+			printf(" %14lf MB/Sec\n", x / K / K);		\
+		else							\
+			printf(" %14lf GB/Sec\n", x / K / K / K);	\
 	} while (0)
 
 struct bench_mem_info {
 	const struct routine *routines;
-	u64 (*do_cycle)(const struct routine *r, size_t len, bool prefault);
-	double (*do_gettimeofday)(const struct routine *r, size_t len, bool prefault);
+	u64 (*do_cycle)(const struct routine *r, size_t len);
+	double (*do_gettimeofday)(const struct routine *r, size_t len);
 	const char *const *usage;
 };
 
 static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t len, double totallen)
 {
 	const struct routine *r = &info->routines[r_idx];
-	double result_bps[2];
-	u64 result_cycle[2];
-	int prefault = no_prefault ? 0 : 1;
-
-	result_cycle[0] = result_cycle[1] = 0ULL;
-	result_bps[0] = result_bps[1] = 0.0;
+	double result_bps = 0.0;
+	u64 result_cycle = 0;
 
 	printf("Routine %s (%s)\n", r->name, r->desc);
 
 	if (bench_format == BENCH_FORMAT_DEFAULT)
 		printf("# Copying %s Bytes ...\n\n", length_str);
 
-	if (!only_prefault && prefault) {
-		/* Show both results: */
-		if (use_cycle) {
-			result_cycle[0] = info->do_cycle(r, len, false);
-			result_cycle[1] = info->do_cycle(r, len, true);
-		} else {
-			result_bps[0]   = info->do_gettimeofday(r, len, false);
-			result_bps[1]   = info->do_gettimeofday(r, len, true);
-		}
+	if (use_cycle) {
+		result_cycle = info->do_cycle(r, len);
 	} else {
-		if (use_cycle)
-			result_cycle[prefault] = info->do_cycle(r, len, only_prefault);
-		else
-			result_bps[prefault] = info->do_gettimeofday(r, len, only_prefault);
+		result_bps = info->do_gettimeofday(r, len);
 	}
 
 	switch (bench_format) {
 	case BENCH_FORMAT_DEFAULT:
-		if (!only_prefault && prefault) {
-			if (use_cycle) {
-				printf(" %14lf Cycle/Byte\n",
-					(double)result_cycle[0]
-					/ totallen);
-				printf(" %14lf Cycle/Byte (with prefault)\n",
-					(double)result_cycle[1]
-					/ totallen);
-			} else {
-				print_bps(result_bps[0]);
-				printf("\n");
-				print_bps(result_bps[1]);
-				printf(" (with prefault)\n");
-			}
+		if (use_cycle) {
+			printf(" %14lf Cycle/Byte\n", (double)result_cycle/totallen);
 		} else {
-			if (use_cycle) {
-				printf(" %14lf Cycle/Byte",
-					(double)result_cycle[prefault]
-					/ totallen);
-			} else
-				print_bps(result_bps[prefault]);
-
-			printf("%s\n", only_prefault ? " (with prefault)" : "");
+			print_bps(result_bps);
 		}
 		break;
+
 	case BENCH_FORMAT_SIMPLE:
-		if (!only_prefault && prefault) {
-			if (use_cycle) {
-				printf("%lf %lf\n",
-					(double)result_cycle[0] / totallen,
-					(double)result_cycle[1] / totallen);
-			} else {
-				printf("%lf %lf\n",
-					result_bps[0], result_bps[1]);
-			}
+		if (use_cycle) {
+			printf("%lf\n", (double)result_cycle/totallen);
 		} else {
-			if (use_cycle) {
-				printf("%lf\n", (double)result_cycle[prefault]
-					/ totallen);
-			} else
-				printf("%lf\n", result_bps[prefault]);
+			printf("%lf\n", result_bps);
 		}
 		break;
+
 	default:
-		/* Reaching this means there's some disaster: */
-		die("unknown format: %d\n", bench_format);
+		BUG_ON(1);
 		break;
 	}
 }
@@ -219,11 +170,6 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *
 
 	argc = parse_options(argc, argv, options, info->usage, 0);
 
-	if (no_prefault && only_prefault) {
-		fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n");
-		return 1;
-	}
-
 	if (use_cycle)
 		init_cycle();
 
@@ -235,10 +181,6 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *
 		return 1;
 	}
 
-	/* Same as without specifying either of prefault and no-prefault: */
-	if (only_prefault && no_prefault)
-		only_prefault = no_prefault = false;
-
 	if (!strncmp(routine, "all", 3)) {
 		for (i = 0; info->routines[i].name; i++)
 			__bench_mem_routine(info, i, len, totallen);
@@ -278,7 +220,7 @@ static void memcpy_alloc_mem(void **dst, void **src, size_t length)
 	memset(*src, 0, length);
 }
 
-static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault)
+static u64 do_memcpy_cycle(const struct routine *r, size_t len)
 {
 	u64 cycle_start = 0ULL, cycle_end = 0ULL;
 	void *src = NULL, *dst = NULL;
@@ -287,8 +229,11 @@ static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault)
 
 	memcpy_alloc_mem(&dst, &src, len);
 
-	if (prefault)
-		fn(dst, src, len);
+	/*
+	 * We prefault the freshly allocated memory range here,
+	 * to not measure page fault overhead:
+	 */
+	fn(dst, src, len);
 
 	cycle_start = get_cycle();
 	for (i = 0; i < iterations; ++i)
@@ -300,7 +245,7 @@ static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault)
 	return cycle_end - cycle_start;
 }
 
-static double do_memcpy_gettimeofday(const struct routine *r, size_t len, bool prefault)
+static double do_memcpy_gettimeofday(const struct routine *r, size_t len)
 {
 	struct timeval tv_start, tv_end, tv_diff;
 	memcpy_t fn = r->fn.memcpy;
@@ -309,8 +254,11 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len, bool p
 
 	memcpy_alloc_mem(&dst, &src, len);
 
-	if (prefault)
-		fn(dst, src, len);
+	/*
+	 * We prefault the freshly allocated memory range here,
+	 * to not measure page fault overhead:
+	 */
+	fn(dst, src, len);
 
 	BUG_ON(gettimeofday(&tv_start, NULL));
 	for (i = 0; i < iterations; ++i)
@@ -321,6 +269,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len, bool p
 
 	free(src);
 	free(dst);
+
 	return (double)(((double)len * iterations) / timeval2double(&tv_diff));
 }
 
@@ -343,7 +292,7 @@ static void memset_alloc_mem(void **dst, size_t length)
 		die("memory allocation failed - maybe length is too large?\n");
 }
 
-static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault)
+static u64 do_memset_cycle(const struct routine *r, size_t len)
 {
 	u64 cycle_start = 0ULL, cycle_end = 0ULL;
 	memset_t fn = r->fn.memset;
@@ -352,8 +301,11 @@ static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault)
 
 	memset_alloc_mem(&dst, len);
 
-	if (prefault)
-		fn(dst, -1, len);
+	/*
+	 * We prefault the freshly allocated memory range here,
+	 * to not measure page fault overhead:
+	 */
+	fn(dst, -1, len);
 
 	cycle_start = get_cycle();
 	for (i = 0; i < iterations; ++i)
@@ -364,8 +316,7 @@ static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault)
 	return cycle_end - cycle_start;
 }
 
-static double do_memset_gettimeofday(const struct routine *r, size_t len,
-				     bool prefault)
+static double do_memset_gettimeofday(const struct routine *r, size_t len)
 {
 	struct timeval tv_start, tv_end, tv_diff;
 	memset_t fn = r->fn.memset;
@@ -374,8 +325,11 @@ static double do_memset_gettimeofday(const struct routine *r, size_t len,
 
 	memset_alloc_mem(&dst, len);
 
-	if (prefault)
-		fn(dst, -1, len);
+	/*
+	 * We prefault the freshly allocated memory range here,
+	 * to not measure page fault overhead:
+	 */
+	fn(dst, -1, len);
 
 	BUG_ON(gettimeofday(&tv_start, NULL));
 	for (i = 0; i < iterations; ++i)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1250439 — [PATCH 04/14] perf/bench: Rename 'mem-memcpy.c' => 'mem-functions.c'

FromIngo Molnar <mingo@kernel.org>
Date2015-10-19 10:20 +0200
Subject[PATCH 04/14] perf/bench: Rename 'mem-memcpy.c' => 'mem-functions.c'
Message-ID<qldPI-74y-25@gated-at.bofh.it>
In reply to#1250418
So mem-memcpy.c started out as a simple memcpy() benchmark, then
it grew memset() functionality and now I plan to add string copy
benchmarks as well.

This makes the file name a misnomer: rename it to the more generic
mem-functions.c name.

Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 tools/perf/bench/Build           |   2 +-
 tools/perf/bench/mem-functions.c | 420 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 421 insertions(+), 1 deletion(-)

diff --git a/tools/perf/bench/Build b/tools/perf/bench/Build
index 573e28896038..60bf11943047 100644
--- a/tools/perf/bench/Build
+++ b/tools/perf/bench/Build
@@ -1,6 +1,6 @@
 perf-y += sched-messaging.o
 perf-y += sched-pipe.o
-perf-y += mem-memcpy.o
+perf-y += mem-functions.o
 perf-y += futex-hash.o
 perf-y += futex-wake.o
 perf-y += futex-wake-parallel.o
diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c
new file mode 100644
index 000000000000..8f91c2e6b459
--- /dev/null
+++ b/tools/perf/bench/mem-functions.c
@@ -0,0 +1,420 @@
+/*
+ * mem-functions.c
+ *
+ * Simple memcpy() and memset() benchmarks.
+ *
+ * Written by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
+ */
+
+#include "../perf.h"
+#include "../util/util.h"
+#include "../util/parse-options.h"
+#include "../util/header.h"
+#include "../util/cloexec.h"
+#include "bench.h"
+#include "mem-memcpy-arch.h"
+#include "mem-memset-arch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <errno.h>
+
+#define K 1024
+
+static const char	*length_str	= "1MB";
+static const char	*routine	= "all";
+static int		iterations	= 1;
+static bool		use_cycle;
+static int		cycle_fd;
+static bool		only_prefault;
+static bool		no_prefault;
+
+static const struct option options[] = {
+	OPT_STRING('l', "length", &length_str, "1MB",
+		    "Specify length of memory to copy. "
+		    "Available units: B, KB, MB, GB and TB (upper and lower)"),
+	OPT_STRING('r', "routine", &routine, "all",
+		    "Specify routine to copy, \"all\" runs all available routines"),
+	OPT_INTEGER('i', "iterations", &iterations,
+		    "repeat memcpy() invocation this number of times"),
+	OPT_BOOLEAN('c', "cycle", &use_cycle,
+		    "Use cycles event instead of gettimeofday() for measuring"),
+	OPT_BOOLEAN('o', "only-prefault", &only_prefault,
+		    "Show only the result with page faults before memcpy()"),
+	OPT_BOOLEAN('n', "no-prefault", &no_prefault,
+		    "Show only the result without page faults before memcpy()"),
+	OPT_END()
+};
+
+typedef void *(*memcpy_t)(void *, const void *, size_t);
+typedef void *(*memset_t)(void *, int, size_t);
+
+struct routine {
+	const char *name;
+	const char *desc;
+	union {
+		memcpy_t memcpy;
+		memset_t memset;
+	} fn;
+};
+
+struct routine memcpy_routines[] = {
+	{ .name		= "default",
+	  .desc		= "Default memcpy() provided by glibc",
+	  .fn.memcpy	= memcpy },
+
+#ifdef HAVE_ARCH_X86_64_SUPPORT
+# define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn},
+# include "mem-memcpy-x86-64-asm-def.h"
+# undef MEMCPY_FN
+#endif
+
+	{ NULL, }
+};
+
+static const char * const bench_mem_memcpy_usage[] = {
+	"perf bench mem memcpy <options>",
+	NULL
+};
+
+static struct perf_event_attr cycle_attr = {
+	.type		= PERF_TYPE_HARDWARE,
+	.config		= PERF_COUNT_HW_CPU_CYCLES
+};
+
+static void init_cycle(void)
+{
+	cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, perf_event_open_cloexec_flag());
+
+	if (cycle_fd < 0 && errno == ENOSYS)
+		die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
+	else
+		BUG_ON(cycle_fd < 0);
+}
+
+static u64 get_cycle(void)
+{
+	int ret;
+	u64 clk;
+
+	ret = read(cycle_fd, &clk, sizeof(u64));
+	BUG_ON(ret != sizeof(u64));
+
+	return clk;
+}
+
+static double timeval2double(struct timeval *ts)
+{
+	return (double)ts->tv_sec + (double)ts->tv_usec / (double)1000000;
+}
+
+#define print_bps(x) do {					\
+		if (x < K)					\
+			printf(" %14lf B/Sec", x);		\
+		else if (x < K * K)				\
+			printf(" %14lfd KB/Sec", x / K);	\
+		else if (x < K * K * K)				\
+			printf(" %14lf MB/Sec", x / K / K);	\
+		else						\
+			printf(" %14lf GB/Sec", x / K / K / K); \
+	} while (0)
+
+struct bench_mem_info {
+	const struct routine *routines;
+	u64 (*do_cycle)(const struct routine *r, size_t len, bool prefault);
+	double (*do_gettimeofday)(const struct routine *r, size_t len, bool prefault);
+	const char *const *usage;
+};
+
+static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t len, double totallen)
+{
+	const struct routine *r = &info->routines[r_idx];
+	double result_bps[2];
+	u64 result_cycle[2];
+	int prefault = no_prefault ? 0 : 1;
+
+	result_cycle[0] = result_cycle[1] = 0ULL;
+	result_bps[0] = result_bps[1] = 0.0;
+
+	printf("Routine %s (%s)\n", r->name, r->desc);
+
+	if (bench_format == BENCH_FORMAT_DEFAULT)
+		printf("# Copying %s Bytes ...\n\n", length_str);
+
+	if (!only_prefault && prefault) {
+		/* Show both results: */
+		if (use_cycle) {
+			result_cycle[0] = info->do_cycle(r, len, false);
+			result_cycle[1] = info->do_cycle(r, len, true);
+		} else {
+			result_bps[0]   = info->do_gettimeofday(r, len, false);
+			result_bps[1]   = info->do_gettimeofday(r, len, true);
+		}
+	} else {
+		if (use_cycle)
+			result_cycle[prefault] = info->do_cycle(r, len, only_prefault);
+		else
+			result_bps[prefault] = info->do_gettimeofday(r, len, only_prefault);
+	}
+
+	switch (bench_format) {
+	case BENCH_FORMAT_DEFAULT:
+		if (!only_prefault && prefault) {
+			if (use_cycle) {
+				printf(" %14lf Cycle/Byte\n",
+					(double)result_cycle[0]
+					/ totallen);
+				printf(" %14lf Cycle/Byte (with prefault)\n",
+					(double)result_cycle[1]
+					/ totallen);
+			} else {
+				print_bps(result_bps[0]);
+				printf("\n");
+				print_bps(result_bps[1]);
+				printf(" (with prefault)\n");
+			}
+		} else {
+			if (use_cycle) {
+				printf(" %14lf Cycle/Byte",
+					(double)result_cycle[prefault]
+					/ totallen);
+			} else
+				print_bps(result_bps[prefault]);
+
+			printf("%s\n", only_prefault ? " (with prefault)" : "");
+		}
+		break;
+	case BENCH_FORMAT_SIMPLE:
+		if (!only_prefault && prefault) {
+			if (use_cycle) {
+				printf("%lf %lf\n",
+					(double)result_cycle[0] / totallen,
+					(double)result_cycle[1] / totallen);
+			} else {
+				printf("%lf %lf\n",
+					result_bps[0], result_bps[1]);
+			}
+		} else {
+			if (use_cycle) {
+				printf("%lf\n", (double)result_cycle[prefault]
+					/ totallen);
+			} else
+				printf("%lf\n", result_bps[prefault]);
+		}
+		break;
+	default:
+		/* Reaching this means there's some disaster: */
+		die("unknown format: %d\n", bench_format);
+		break;
+	}
+}
+
+static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *info)
+{
+	int i;
+	size_t len;
+	double totallen;
+
+	argc = parse_options(argc, argv, options, info->usage, 0);
+
+	if (no_prefault && only_prefault) {
+		fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n");
+		return 1;
+	}
+
+	if (use_cycle)
+		init_cycle();
+
+	len = (size_t)perf_atoll((char *)length_str);
+	totallen = (double)len * iterations;
+
+	if ((s64)len <= 0) {
+		fprintf(stderr, "Invalid length:%s\n", length_str);
+		return 1;
+	}
+
+	/* Same as without specifying either of prefault and no-prefault: */
+	if (only_prefault && no_prefault)
+		only_prefault = no_prefault = false;
+
+	if (!strncmp(routine, "all", 3)) {
+		for (i = 0; info->routines[i].name; i++)
+			__bench_mem_routine(info, i, len, totallen);
+		return 0;
+	}
+
+	for (i = 0; info->routines[i].name; i++) {
+		if (!strcmp(info->routines[i].name, routine))
+			break;
+	}
+	if (!info->routines[i].name) {
+		printf("Unknown routine:%s\n", routine);
+		printf("Available routines...\n");
+		for (i = 0; info->routines[i].name; i++) {
+			printf("\t%s ... %s\n",
+			       info->routines[i].name, info->routines[i].desc);
+		}
+		return 1;
+	}
+
+	__bench_mem_routine(info, i, len, totallen);
+
+	return 0;
+}
+
+static void memcpy_alloc_mem(void **dst, void **src, size_t length)
+{
+	*dst = zalloc(length);
+	if (!*dst)
+		die("memory allocation failed - maybe length is too large?\n");
+
+	*src = zalloc(length);
+	if (!*src)
+		die("memory allocation failed - maybe length is too large?\n");
+
+	/* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */
+	memset(*src, 0, length);
+}
+
+static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault)
+{
+	u64 cycle_start = 0ULL, cycle_end = 0ULL;
+	void *src = NULL, *dst = NULL;
+	memcpy_t fn = r->fn.memcpy;
+	int i;
+
+	memcpy_alloc_mem(&dst, &src, len);
+
+	if (prefault)
+		fn(dst, src, len);
+
+	cycle_start = get_cycle();
+	for (i = 0; i < iterations; ++i)
+		fn(dst, src, len);
+	cycle_end = get_cycle();
+
+	free(src);
+	free(dst);
+	return cycle_end - cycle_start;
+}
+
+static double do_memcpy_gettimeofday(const struct routine *r, size_t len, bool prefault)
+{
+	struct timeval tv_start, tv_end, tv_diff;
+	memcpy_t fn = r->fn.memcpy;
+	void *src = NULL, *dst = NULL;
+	int i;
+
+	memcpy_alloc_mem(&dst, &src, len);
+
+	if (prefault)
+		fn(dst, src, len);
+
+	BUG_ON(gettimeofday(&tv_start, NULL));
+	for (i = 0; i < iterations; ++i)
+		fn(dst, src, len);
+	BUG_ON(gettimeofday(&tv_end, NULL));
+
+	timersub(&tv_end, &tv_start, &tv_diff);
+
+	free(src);
+	free(dst);
+	return (double)(((double)len * iterations) / timeval2double(&tv_diff));
+}
+
+int bench_mem_memcpy(int argc, const char **argv, const char *prefix __unused)
+{
+	struct bench_mem_info info = {
+		.routines		= memcpy_routines,
+		.do_cycle		= do_memcpy_cycle,
+		.do_gettimeofday	= do_memcpy_gettimeofday,
+		.usage			= bench_mem_memcpy_usage,
+	};
+
+	return bench_mem_common(argc, argv, &info);
+}
+
+static void memset_alloc_mem(void **dst, size_t length)
+{
+	*dst = zalloc(length);
+	if (!*dst)
+		die("memory allocation failed - maybe length is too large?\n");
+}
+
+static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault)
+{
+	u64 cycle_start = 0ULL, cycle_end = 0ULL;
+	memset_t fn = r->fn.memset;
+	void *dst = NULL;
+	int i;
+
+	memset_alloc_mem(&dst, len);
+
+	if (prefault)
+		fn(dst, -1, len);
+
+	cycle_start = get_cycle();
+	for (i = 0; i < iterations; ++i)
+		fn(dst, i, len);
+	cycle_end = get_cycle();
+
+	free(dst);
+	return cycle_end - cycle_start;
+}
+
+static double do_memset_gettimeofday(const struct routine *r, size_t len,
+				     bool prefault)
+{
+	struct timeval tv_start, tv_end, tv_diff;
+	memset_t fn = r->fn.memset;
+	void *dst = NULL;
+	int i;
+
+	memset_alloc_mem(&dst, len);
+
+	if (prefault)
+		fn(dst, -1, len);
+
+	BUG_ON(gettimeofday(&tv_start, NULL));
+	for (i = 0; i < iterations; ++i)
+		fn(dst, i, len);
+	BUG_ON(gettimeofday(&tv_end, NULL));
+
+	timersub(&tv_end, &tv_start, &tv_diff);
+
+	free(dst);
+	return (double)(((double)len * iterations) / timeval2double(&tv_diff));
+}
+
+static const char * const bench_mem_memset_usage[] = {
+	"perf bench mem memset <options>",
+	NULL
+};
+
+static const struct routine memset_routines[] = {
+	{ .name		= "default",
+	  .desc		= "Default memset() provided by glibc",
+	  .fn.memset	= memset },
+
+#ifdef HAVE_ARCH_X86_64_SUPPORT
+# define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn },
+# include "mem-memset-x86-64-asm-def.h"
+# undef MEMSET_FN
+#endif
+
+	{ NULL, }
+};
+
+int bench_mem_memset(int argc, const char **argv, const char *prefix __unused)
+{
+	struct bench_mem_info info = {
+		.routines		= memset_routines,
+		.do_cycle		= do_memset_cycle,
+		.do_gettimeofday	= do_memset_gettimeofday,
+		.usage			= bench_mem_memset_usage,
+	};
+
+	return bench_mem_common(argc, argv, &info);
+}
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1250994 — Re: [PATCH 04/14] perf/bench: Rename 'mem-memcpy.c' => 'mem-functions.c'

FromArnaldo Carvalho de Melo <acme@redhat.com>
Date2015-10-19 20:40 +0200
SubjectRe: [PATCH 04/14] perf/bench: Rename 'mem-memcpy.c' => 'mem-functions.c'
Message-ID<qlnvI-4hK-9@gated-at.bofh.it>
In reply to#1250439
Em Mon, Oct 19, 2015 at 04:35:20PM -0200, Arnaldo Carvalho de Melo escreveu:
> Em Mon, Oct 19, 2015 at 10:04:20AM +0200, Ingo Molnar escreveu:
> > So mem-memcpy.c started out as a simple memcpy() benchmark, then
> > it grew memset() functionality and now I plan to add string copy
> > benchmarks as well.
> > 
> > This makes the file name a misnomer: rename it to the more generic
> > mem-functions.c name.
> > 
> > Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
> > Cc: David Ahern <dsahern@gmail.com>
> > Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
> > Cc: Jiri Olsa <jolsa@redhat.com>
> > Cc: Linus Torvalds <torvalds@linux-foundation.org>
> > Cc: Namhyung Kim <namhyung@kernel.org>
> > Cc: Peter Zijlstra <peterz@infradead.org>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: linux-kernel@vger.kernel.org
> > Signed-off-by: Ingo Molnar <mingo@kernel.org>
> > ---
> >  tools/perf/bench/Build           |   2 +-
> >  tools/perf/bench/mem-functions.c | 420 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 
> Oops, this is not renaming anything, right? And it also introducs
> __unused usage, which breaks the build.
> 
> Lemme try to do it...

Just after applying this patch, I tried a diff and figure this, fixing
it by just renaming it.

$ diff -u tools/perf/bench/mem-memcpy.c tools/perf/bench/mem-functions.c
--- tools/perf/bench/mem-memcpy.c	2015-10-19 15:29:08.761643798 -0300
+++ tools/perf/bench/mem-functions.c	2015-10-19 15:35:34.986776289 -0300
@@ -1,7 +1,7 @@
 /*
- * mem-memcpy.c
+ * mem-functions.c
  *
- * Simple memcpy() and memset() benchmarks
+ * Simple memcpy() and memset() benchmarks.
  *
  * Written by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
  */
@@ -324,7 +324,7 @@
 	return (double)(((double)len * iterations) / timeval2double(&tv_diff));
 }
 
-int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unused)
+int bench_mem_memcpy(int argc, const char **argv, const char *prefix __unused)
 {
 	struct bench_mem_info info = {
 		.routines		= memcpy_routines,
@@ -407,7 +407,7 @@
 	{ NULL, }
 };
 
-int bench_mem_memset(int argc, const char **argv, const char *prefix __maybe_unused)
+int bench_mem_memset(int argc, const char **argv, const char *prefix __unused)
 {
 	struct bench_mem_info info = {
 		.routines		= memset_routines,
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1250997 — Re: [PATCH 04/14] perf/bench: Rename 'mem-memcpy.c' => 'mem-functions.c'

FromArnaldo Carvalho de Melo <acme@redhat.com>
Date2015-10-19 20:40 +0200
SubjectRe: [PATCH 04/14] perf/bench: Rename 'mem-memcpy.c' => 'mem-functions.c'
Message-ID<qlnvI-4hK-11@gated-at.bofh.it>
In reply to#1250439
Em Mon, Oct 19, 2015 at 10:04:20AM +0200, Ingo Molnar escreveu:
> So mem-memcpy.c started out as a simple memcpy() benchmark, then
> it grew memset() functionality and now I plan to add string copy
> benchmarks as well.
> 
> This makes the file name a misnomer: rename it to the more generic
> mem-functions.c name.
> 
> Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
> Cc: David Ahern <dsahern@gmail.com>
> Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
> Cc: Jiri Olsa <jolsa@redhat.com>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Ingo Molnar <mingo@kernel.org>
> ---
>  tools/perf/bench/Build           |   2 +-
>  tools/perf/bench/mem-functions.c | 420 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Oops, this is not renaming anything, right? And it also introducs
__unused usage, which breaks the build.

Lemme try to do it...

- Arnaldo

>  2 files changed, 421 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/perf/bench/Build b/tools/perf/bench/Build
> index 573e28896038..60bf11943047 100644
> --- a/tools/perf/bench/Build
> +++ b/tools/perf/bench/Build
> @@ -1,6 +1,6 @@
>  perf-y += sched-messaging.o
>  perf-y += sched-pipe.o
> -perf-y += mem-memcpy.o
> +perf-y += mem-functions.o
>  perf-y += futex-hash.o
>  perf-y += futex-wake.o
>  perf-y += futex-wake-parallel.o
> diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c
> new file mode 100644
> index 000000000000..8f91c2e6b459
> --- /dev/null
> +++ b/tools/perf/bench/mem-functions.c
> @@ -0,0 +1,420 @@
> +/*
> + * mem-functions.c
> + *
> + * Simple memcpy() and memset() benchmarks.
> + *
> + * Written by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
> + */
> +
> +#include "../perf.h"
> +#include "../util/util.h"
> +#include "../util/parse-options.h"
> +#include "../util/header.h"
> +#include "../util/cloexec.h"
> +#include "bench.h"
> +#include "mem-memcpy-arch.h"
> +#include "mem-memset-arch.h"
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/time.h>
> +#include <errno.h>
> +
> +#define K 1024
> +
> +static const char	*length_str	= "1MB";
> +static const char	*routine	= "all";
> +static int		iterations	= 1;
> +static bool		use_cycle;
> +static int		cycle_fd;
> +static bool		only_prefault;
> +static bool		no_prefault;
> +
> +static const struct option options[] = {
> +	OPT_STRING('l', "length", &length_str, "1MB",
> +		    "Specify length of memory to copy. "
> +		    "Available units: B, KB, MB, GB and TB (upper and lower)"),
> +	OPT_STRING('r', "routine", &routine, "all",
> +		    "Specify routine to copy, \"all\" runs all available routines"),
> +	OPT_INTEGER('i', "iterations", &iterations,
> +		    "repeat memcpy() invocation this number of times"),
> +	OPT_BOOLEAN('c', "cycle", &use_cycle,
> +		    "Use cycles event instead of gettimeofday() for measuring"),
> +	OPT_BOOLEAN('o', "only-prefault", &only_prefault,
> +		    "Show only the result with page faults before memcpy()"),
> +	OPT_BOOLEAN('n', "no-prefault", &no_prefault,
> +		    "Show only the result without page faults before memcpy()"),
> +	OPT_END()
> +};
> +
> +typedef void *(*memcpy_t)(void *, const void *, size_t);
> +typedef void *(*memset_t)(void *, int, size_t);
> +
> +struct routine {
> +	const char *name;
> +	const char *desc;
> +	union {
> +		memcpy_t memcpy;
> +		memset_t memset;
> +	} fn;
> +};
> +
> +struct routine memcpy_routines[] = {
> +	{ .name		= "default",
> +	  .desc		= "Default memcpy() provided by glibc",
> +	  .fn.memcpy	= memcpy },
> +
> +#ifdef HAVE_ARCH_X86_64_SUPPORT
> +# define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn},
> +# include "mem-memcpy-x86-64-asm-def.h"
> +# undef MEMCPY_FN
> +#endif
> +
> +	{ NULL, }
> +};
> +
> +static const char * const bench_mem_memcpy_usage[] = {
> +	"perf bench mem memcpy <options>",
> +	NULL
> +};
> +
> +static struct perf_event_attr cycle_attr = {
> +	.type		= PERF_TYPE_HARDWARE,
> +	.config		= PERF_COUNT_HW_CPU_CYCLES
> +};
> +
> +static void init_cycle(void)
> +{
> +	cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, perf_event_open_cloexec_flag());
> +
> +	if (cycle_fd < 0 && errno == ENOSYS)
> +		die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
> +	else
> +		BUG_ON(cycle_fd < 0);
> +}
> +
> +static u64 get_cycle(void)
> +{
> +	int ret;
> +	u64 clk;
> +
> +	ret = read(cycle_fd, &clk, sizeof(u64));
> +	BUG_ON(ret != sizeof(u64));
> +
> +	return clk;
> +}
> +
> +static double timeval2double(struct timeval *ts)
> +{
> +	return (double)ts->tv_sec + (double)ts->tv_usec / (double)1000000;
> +}
> +
> +#define print_bps(x) do {					\
> +		if (x < K)					\
> +			printf(" %14lf B/Sec", x);		\
> +		else if (x < K * K)				\
> +			printf(" %14lfd KB/Sec", x / K);	\
> +		else if (x < K * K * K)				\
> +			printf(" %14lf MB/Sec", x / K / K);	\
> +		else						\
> +			printf(" %14lf GB/Sec", x / K / K / K); \
> +	} while (0)
> +
> +struct bench_mem_info {
> +	const struct routine *routines;
> +	u64 (*do_cycle)(const struct routine *r, size_t len, bool prefault);
> +	double (*do_gettimeofday)(const struct routine *r, size_t len, bool prefault);
> +	const char *const *usage;
> +};
> +
> +static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t len, double totallen)
> +{
> +	const struct routine *r = &info->routines[r_idx];
> +	double result_bps[2];
> +	u64 result_cycle[2];
> +	int prefault = no_prefault ? 0 : 1;
> +
> +	result_cycle[0] = result_cycle[1] = 0ULL;
> +	result_bps[0] = result_bps[1] = 0.0;
> +
> +	printf("Routine %s (%s)\n", r->name, r->desc);
> +
> +	if (bench_format == BENCH_FORMAT_DEFAULT)
> +		printf("# Copying %s Bytes ...\n\n", length_str);
> +
> +	if (!only_prefault && prefault) {
> +		/* Show both results: */
> +		if (use_cycle) {
> +			result_cycle[0] = info->do_cycle(r, len, false);
> +			result_cycle[1] = info->do_cycle(r, len, true);
> +		} else {
> +			result_bps[0]   = info->do_gettimeofday(r, len, false);
> +			result_bps[1]   = info->do_gettimeofday(r, len, true);
> +		}
> +	} else {
> +		if (use_cycle)
> +			result_cycle[prefault] = info->do_cycle(r, len, only_prefault);
> +		else
> +			result_bps[prefault] = info->do_gettimeofday(r, len, only_prefault);
> +	}
> +
> +	switch (bench_format) {
> +	case BENCH_FORMAT_DEFAULT:
> +		if (!only_prefault && prefault) {
> +			if (use_cycle) {
> +				printf(" %14lf Cycle/Byte\n",
> +					(double)result_cycle[0]
> +					/ totallen);
> +				printf(" %14lf Cycle/Byte (with prefault)\n",
> +					(double)result_cycle[1]
> +					/ totallen);
> +			} else {
> +				print_bps(result_bps[0]);
> +				printf("\n");
> +				print_bps(result_bps[1]);
> +				printf(" (with prefault)\n");
> +			}
> +		} else {
> +			if (use_cycle) {
> +				printf(" %14lf Cycle/Byte",
> +					(double)result_cycle[prefault]
> +					/ totallen);
> +			} else
> +				print_bps(result_bps[prefault]);
> +
> +			printf("%s\n", only_prefault ? " (with prefault)" : "");
> +		}
> +		break;
> +	case BENCH_FORMAT_SIMPLE:
> +		if (!only_prefault && prefault) {
> +			if (use_cycle) {
> +				printf("%lf %lf\n",
> +					(double)result_cycle[0] / totallen,
> +					(double)result_cycle[1] / totallen);
> +			} else {
> +				printf("%lf %lf\n",
> +					result_bps[0], result_bps[1]);
> +			}
> +		} else {
> +			if (use_cycle) {
> +				printf("%lf\n", (double)result_cycle[prefault]
> +					/ totallen);
> +			} else
> +				printf("%lf\n", result_bps[prefault]);
> +		}
> +		break;
> +	default:
> +		/* Reaching this means there's some disaster: */
> +		die("unknown format: %d\n", bench_format);
> +		break;
> +	}
> +}
> +
> +static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *info)
> +{
> +	int i;
> +	size_t len;
> +	double totallen;
> +
> +	argc = parse_options(argc, argv, options, info->usage, 0);
> +
> +	if (no_prefault && only_prefault) {
> +		fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n");
> +		return 1;
> +	}
> +
> +	if (use_cycle)
> +		init_cycle();
> +
> +	len = (size_t)perf_atoll((char *)length_str);
> +	totallen = (double)len * iterations;
> +
> +	if ((s64)len <= 0) {
> +		fprintf(stderr, "Invalid length:%s\n", length_str);
> +		return 1;
> +	}
> +
> +	/* Same as without specifying either of prefault and no-prefault: */
> +	if (only_prefault && no_prefault)
> +		only_prefault = no_prefault = false;
> +
> +	if (!strncmp(routine, "all", 3)) {
> +		for (i = 0; info->routines[i].name; i++)
> +			__bench_mem_routine(info, i, len, totallen);
> +		return 0;
> +	}
> +
> +	for (i = 0; info->routines[i].name; i++) {
> +		if (!strcmp(info->routines[i].name, routine))
> +			break;
> +	}
> +	if (!info->routines[i].name) {
> +		printf("Unknown routine:%s\n", routine);
> +		printf("Available routines...\n");
> +		for (i = 0; info->routines[i].name; i++) {
> +			printf("\t%s ... %s\n",
> +			       info->routines[i].name, info->routines[i].desc);
> +		}
> +		return 1;
> +	}
> +
> +	__bench_mem_routine(info, i, len, totallen);
> +
> +	return 0;
> +}
> +
> +static void memcpy_alloc_mem(void **dst, void **src, size_t length)
> +{
> +	*dst = zalloc(length);
> +	if (!*dst)
> +		die("memory allocation failed - maybe length is too large?\n");
> +
> +	*src = zalloc(length);
> +	if (!*src)
> +		die("memory allocation failed - maybe length is too large?\n");
> +
> +	/* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */
> +	memset(*src, 0, length);
> +}
> +
> +static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault)
> +{
> +	u64 cycle_start = 0ULL, cycle_end = 0ULL;
> +	void *src = NULL, *dst = NULL;
> +	memcpy_t fn = r->fn.memcpy;
> +	int i;
> +
> +	memcpy_alloc_mem(&dst, &src, len);
> +
> +	if (prefault)
> +		fn(dst, src, len);
> +
> +	cycle_start = get_cycle();
> +	for (i = 0; i < iterations; ++i)
> +		fn(dst, src, len);
> +	cycle_end = get_cycle();
> +
> +	free(src);
> +	free(dst);
> +	return cycle_end - cycle_start;
> +}
> +
> +static double do_memcpy_gettimeofday(const struct routine *r, size_t len, bool prefault)
> +{
> +	struct timeval tv_start, tv_end, tv_diff;
> +	memcpy_t fn = r->fn.memcpy;
> +	void *src = NULL, *dst = NULL;
> +	int i;
> +
> +	memcpy_alloc_mem(&dst, &src, len);
> +
> +	if (prefault)
> +		fn(dst, src, len);
> +
> +	BUG_ON(gettimeofday(&tv_start, NULL));
> +	for (i = 0; i < iterations; ++i)
> +		fn(dst, src, len);
> +	BUG_ON(gettimeofday(&tv_end, NULL));
> +
> +	timersub(&tv_end, &tv_start, &tv_diff);
> +
> +	free(src);
> +	free(dst);
> +	return (double)(((double)len * iterations) / timeval2double(&tv_diff));
> +}
> +
> +int bench_mem_memcpy(int argc, const char **argv, const char *prefix __unused)
> +{
> +	struct bench_mem_info info = {
> +		.routines		= memcpy_routines,
> +		.do_cycle		= do_memcpy_cycle,
> +		.do_gettimeofday	= do_memcpy_gettimeofday,
> +		.usage			= bench_mem_memcpy_usage,
> +	};
> +
> +	return bench_mem_common(argc, argv, &info);
> +}
> +
> +static void memset_alloc_mem(void **dst, size_t length)
> +{
> +	*dst = zalloc(length);
> +	if (!*dst)
> +		die("memory allocation failed - maybe length is too large?\n");
> +}
> +
> +static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault)
> +{
> +	u64 cycle_start = 0ULL, cycle_end = 0ULL;
> +	memset_t fn = r->fn.memset;
> +	void *dst = NULL;
> +	int i;
> +
> +	memset_alloc_mem(&dst, len);
> +
> +	if (prefault)
> +		fn(dst, -1, len);
> +
> +	cycle_start = get_cycle();
> +	for (i = 0; i < iterations; ++i)
> +		fn(dst, i, len);
> +	cycle_end = get_cycle();
> +
> +	free(dst);
> +	return cycle_end - cycle_start;
> +}
> +
> +static double do_memset_gettimeofday(const struct routine *r, size_t len,
> +				     bool prefault)
> +{
> +	struct timeval tv_start, tv_end, tv_diff;
> +	memset_t fn = r->fn.memset;
> +	void *dst = NULL;
> +	int i;
> +
> +	memset_alloc_mem(&dst, len);
> +
> +	if (prefault)
> +		fn(dst, -1, len);
> +
> +	BUG_ON(gettimeofday(&tv_start, NULL));
> +	for (i = 0; i < iterations; ++i)
> +		fn(dst, i, len);
> +	BUG_ON(gettimeofday(&tv_end, NULL));
> +
> +	timersub(&tv_end, &tv_start, &tv_diff);
> +
> +	free(dst);
> +	return (double)(((double)len * iterations) / timeval2double(&tv_diff));
> +}
> +
> +static const char * const bench_mem_memset_usage[] = {
> +	"perf bench mem memset <options>",
> +	NULL
> +};
> +
> +static const struct routine memset_routines[] = {
> +	{ .name		= "default",
> +	  .desc		= "Default memset() provided by glibc",
> +	  .fn.memset	= memset },
> +
> +#ifdef HAVE_ARCH_X86_64_SUPPORT
> +# define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn },
> +# include "mem-memset-x86-64-asm-def.h"
> +# undef MEMSET_FN
> +#endif
> +
> +	{ NULL, }
> +};
> +
> +int bench_mem_memset(int argc, const char **argv, const char *prefix __unused)
> +{
> +	struct bench_mem_info info = {
> +		.routines		= memset_routines,
> +		.do_cycle		= do_memset_cycle,
> +		.do_gettimeofday	= do_memset_gettimeofday,
> +		.usage			= bench_mem_memset_usage,
> +	};
> +
> +	return bench_mem_common(argc, argv, &info);
> +}
> -- 
> 2.1.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1251365 — [tip:perf/core] perf bench: Rename 'mem-memcpy.c' => ' mem-functions.c'

Fromtip-bot for Ingo Molnar <tipbot@zytor.com>
Date2015-10-20 09:50 +0200
Subject[tip:perf/core] perf bench: Rename 'mem-memcpy.c' => ' mem-functions.c'
Message-ID<qlzQd-5Bb-5@gated-at.bofh.it>
In reply to#1250439
Commit-ID:  9b2fa7f3e7799a335fd839906ab4d45b7d595dc4
Gitweb:     http://git.kernel.org/tip/9b2fa7f3e7799a335fd839906ab4d45b7d595dc4
Author:     Ingo Molnar <mingo@kernel.org>
AuthorDate: Mon, 19 Oct 2015 10:04:20 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 19 Oct 2015 15:39:39 -0300

perf bench: Rename 'mem-memcpy.c' => 'mem-functions.c'

So mem-memcpy.c started out as a simple memcpy() benchmark, then it grew
memset() functionality and now I plan to add string copy benchmarks as
well.

This makes the file name a misnomer: rename it to the more generic
mem-functions.c name.

Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1445241870-24854-5-git-send-email-mingo@kernel.org
[ The "rename" was introducing __unused, wasn't removing the old file,
  and didn't update tools/perf/bench/Build, fix it ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/bench/Build                             | 2 +-
 tools/perf/bench/{mem-memcpy.c => mem-functions.c} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/bench/Build b/tools/perf/bench/Build
index 573e288..60bf119 100644
--- a/tools/perf/bench/Build
+++ b/tools/perf/bench/Build
@@ -1,6 +1,6 @@
 perf-y += sched-messaging.o
 perf-y += sched-pipe.o
-perf-y += mem-memcpy.o
+perf-y += mem-functions.o
 perf-y += futex-hash.o
 perf-y += futex-wake.o
 perf-y += futex-wake-parallel.o
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-functions.c
similarity index 100%
rename from tools/perf/bench/mem-memcpy.c
rename to tools/perf/bench/mem-functions.c
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1250440 — [PATCH 03/14] perf/bench: Eliminate unused argument from bench_mem_common()

FromIngo Molnar <mingo@kernel.org>
Date2015-10-19 10:20 +0200
Subject[PATCH 03/14] perf/bench: Eliminate unused argument from bench_mem_common()
Message-ID<qldPI-74y-29@gated-at.bofh.it>
In reply to#1250418
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 tools/perf/bench/mem-memcpy.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
index 263f84171ae5..7acb9b83382c 100644
--- a/tools/perf/bench/mem-memcpy.c
+++ b/tools/perf/bench/mem-memcpy.c
@@ -211,9 +211,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l
 	}
 }
 
-static int bench_mem_common(int argc, const char **argv,
-		     const char *prefix __maybe_unused,
-		     struct bench_mem_info *info)
+static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *info)
 {
 	int i;
 	size_t len;
@@ -326,8 +324,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len, bool p
 	return (double)(((double)len * iterations) / timeval2double(&tv_diff));
 }
 
-int bench_mem_memcpy(int argc, const char **argv,
-		     const char *prefix __maybe_unused)
+int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unused)
 {
 	struct bench_mem_info info = {
 		.routines		= memcpy_routines,
@@ -336,7 +333,7 @@ int bench_mem_memcpy(int argc, const char **argv,
 		.usage			= bench_mem_memcpy_usage,
 	};
 
-	return bench_mem_common(argc, argv, prefix, &info);
+	return bench_mem_common(argc, argv, &info);
 }
 
 static void memset_alloc_mem(void **dst, size_t length)
@@ -419,5 +416,5 @@ int bench_mem_memset(int argc, const char **argv, const char *prefix __maybe_unu
 		.usage			= bench_mem_memset_usage,
 	};
 
-	return bench_mem_common(argc, argv, prefix, &info);
+	return bench_mem_common(argc, argv, &info);
 }
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1251361 — [tip:perf/core] perf bench: Eliminate unused argument from bench_mem_common()

Fromtip-bot for Ingo Molnar <tipbot@zytor.com>
Date2015-10-20 09:50 +0200
Subject[tip:perf/core] perf bench: Eliminate unused argument from bench_mem_common()
Message-ID<qlzQd-5Bb-1@gated-at.bofh.it>
In reply to#1250440
Commit-ID:  2946f59ac31d703738c00c684613d289e8d001ea
Gitweb:     http://git.kernel.org/tip/2946f59ac31d703738c00c684613d289e8d001ea
Author:     Ingo Molnar <mingo@kernel.org>
AuthorDate: Mon, 19 Oct 2015 10:04:19 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 19 Oct 2015 15:29:08 -0300

perf bench: Eliminate unused argument from bench_mem_common()

Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1445241870-24854-4-git-send-email-mingo@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/bench/mem-memcpy.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
index 263f841..7acb9b8 100644
--- a/tools/perf/bench/mem-memcpy.c
+++ b/tools/perf/bench/mem-memcpy.c
@@ -211,9 +211,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l
 	}
 }
 
-static int bench_mem_common(int argc, const char **argv,
-		     const char *prefix __maybe_unused,
-		     struct bench_mem_info *info)
+static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *info)
 {
 	int i;
 	size_t len;
@@ -326,8 +324,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len, bool p
 	return (double)(((double)len * iterations) / timeval2double(&tv_diff));
 }
 
-int bench_mem_memcpy(int argc, const char **argv,
-		     const char *prefix __maybe_unused)
+int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unused)
 {
 	struct bench_mem_info info = {
 		.routines		= memcpy_routines,
@@ -336,7 +333,7 @@ int bench_mem_memcpy(int argc, const char **argv,
 		.usage			= bench_mem_memcpy_usage,
 	};
 
-	return bench_mem_common(argc, argv, prefix, &info);
+	return bench_mem_common(argc, argv, &info);
 }
 
 static void memset_alloc_mem(void **dst, size_t length)
@@ -419,5 +416,5 @@ int bench_mem_memset(int argc, const char **argv, const char *prefix __maybe_unu
 		.usage			= bench_mem_memset_usage,
 	};
 
-	return bench_mem_common(argc, argv, prefix, &info);
+	return bench_mem_common(argc, argv, &info);
 }
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | linux.kernel


csiph-web