Skip to contentSkip to conversation

perf bench: Misc improvements

PATCH In review Ingo Molnar 5 participants 44 messages Oct 19, 2015 – Oct 20, 2015 perf events

lore
Share & tools
lore
#0 lore raw

cover perf bench: Misc improvements

So I'm working towards adding more 'perf bench' benchmarks and found a few rough edges - fixed by the series below.

Thanks,

Ingo

Ingo Molnar (14):
perf/bench: Improve the 'perf bench mem memcpy' code readability perf/bench: Default to all routines in 'perf bench mem' perf/bench: Eliminate unused argument from bench_mem_common() perf/bench: Rename 'mem-memcpy.c' => 'mem-functions.c' perf/bench: Remove the prefaulting complication from 'perf bench mem mem*' perf/bench: List output formatting options on 'perf bench -h' perf/bench/mem: Change 'cycle' to 'cycles'
perf/bench/mem: Rename 'routine' to 'routine_str' perf/bench/mem: Fix 'length' vs. 'size' naming confusion perf/bench/mem: Improve user visible strings
perf/bench/mem: Reorganize the code a bit
perf/bench: Harmonize all the -l/--nr_loops options perf/bench/mem: Rename 'routine' to 'function'
perf/bench: Run benchmarks, don't test them

 tools/perf/bench/Build             |   2 +-
 tools/perf/bench/mem-functions.c   | 379 +++++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/bench/mem-memcpy.c      | 434 ---------------------------------------------------------
 tools/perf/bench/numa.c            |   4 +-
 tools/perf/bench/sched-messaging.c |  10 +-
 tools/perf/builtin-bench.c         |  14 +-
 6 files changed, 394 insertions(+), 449 deletions(-)
 create mode 100644 tools/perf/bench/mem-functions.c
 delete mode 100644 tools/perf/bench/mem-memcpy.c
Signature · 1 line
2.1.4
#1 lore raw

PATCH 1/14 perf/bench: Improve the 'perf bench mem memcpy' code readability

- improve the readability of initializations
- fix unnecessary double negations
- fix ugly line breaks
- fix other small details

Cc Peter Zijlstra <[email protected]>
Cc Arnaldo Carvalho de Melo <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Andrew Morton <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 tools/perf/bench/mem-memcpy.c | 101 ++++++++++++++++++++++++++++----------------------------------
 1 file changed, 45 insertions(+), 56 deletions(-)
tools/perf/bench/mem-memcpy.c +45 -56
index d3dfb7936dcd..27606ff5c4f9 100644
@@ -1,7 +1,7 @@
 /*
  * mem-memcpy.c
  *
- * memcpy: Simple memory copy in various ways
+ * Simple memcpy() and memset() benchmarks
  *
  * Written by Hitoshi Mitake <[email protected]>
  */
@@ -61,20 +61,17 @@ struct routine {
 };
 
 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
+	{ .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,
-	  NULL,
-	  {NULL}   }
+	{ NULL, }
 };
 
 static const char * const bench_mem_memcpy_usage[] = {
@@ -89,8 +86,7 @@ static struct perf_event_attr cycle_attr = {
 
 static void init_cycle(void)
 {
-	cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1,
-				       perf_event_open_cloexec_flag());
+	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");
@@ -111,12 +107,9 @@ static u64 get_cycle(void)
 
 static double timeval2double(struct timeval *ts)
 {
-	return (double)ts->tv_sec +
-		(double)ts->tv_usec / (double)1000000;
+	return (double)ts->tv_sec + (double)ts->tv_usec / (double)1000000;
 }
 
-#define pf (no_prefault ? 0 : 1)
-
 #define print_bps(x) do {					\
 		if (x < K)					\
 			printf(" %14lf B/Sec", x);		\
@@ -140,6 +133,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l
 	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;
@@ -149,8 +143,8 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l
 	if (bench_format == BENCH_FORMAT_DEFAULT)
 		printf("# Copying %s Bytes ...\n\n", length_str);
 
-	if (!only_prefault && !no_prefault) {
-		/* show both of results */
+	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);
@@ -160,14 +154,14 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l
 		}
 	} else {
 		if (use_cycle)
-			result_cycle[pf] = info->do_cycle(r, len, only_prefault);
+			result_cycle[prefault] = info->do_cycle(r, len, only_prefault);
 		else
-			result_bps[pf] = info->do_gettimeofday(r, len, only_prefault);
+			result_bps[prefault] = info->do_gettimeofday(r, len, only_prefault);
 	}
 
 	switch (bench_format) {
 	case BENCH_FORMAT_DEFAULT:
-		if (!only_prefault && !no_prefault) {
+		if (!only_prefault && prefault) {
 			if (use_cycle) {
 				printf(" %14lf Cycle/Byte\n",
 					(double)result_cycle[0]
@@ -184,16 +178,16 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l
 		} else {
 			if (use_cycle) {
 				printf(" %14lf Cycle/Byte",
-					(double)result_cycle[pf]
+					(double)result_cycle[prefault]
 					/ totallen);
 			} else
-				print_bps(result_bps[pf]);
+				print_bps(result_bps[prefault]);
 
 			printf("%s\n", only_prefault ? " (with prefault)" : "");
 		}
 		break;
 	case BENCH_FORMAT_SIMPLE:
-		if (!only_prefault && !no_prefault) {
+		if (!only_prefault && prefault) {
 			if (use_cycle) {
 				printf("%lf %lf\n",
 					(double)result_cycle[0] / totallen,
@@ -204,14 +198,14 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l
 			}
 		} else {
 			if (use_cycle) {
-				printf("%lf\n", (double)result_cycle[pf]
+				printf("%lf\n", (double)result_cycle[prefault]
 					/ totallen);
 			} else
-				printf("%lf\n", result_bps[pf]);
+				printf("%lf\n", result_bps[prefault]);
 		}
 		break;
 	default:
-		/* reaching this means there's some disaster: */
+		/* Reaching this means there's some disaster: */
 		die("unknown format: %d\n", bench_format);
 		break;
 	}
@@ -225,8 +219,7 @@ static int bench_mem_common(int argc, const char **argv,
 	size_t len;
 	double totallen;
 
-	argc = parse_options(argc, argv, options,
-			     info->usage, 0);
+	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");
@@ -244,7 +237,7 @@ static int bench_mem_common(int argc, const char **argv,
 		return 1;
 	}
 
-	/* same to without specifying either of prefault and no-prefault */
+	/* Same as without specifying either of prefault and no-prefault: */
 	if (only_prefault && no_prefault)
 		only_prefault = no_prefault = false;
 
@@ -282,7 +275,8 @@ static void memcpy_alloc_mem(void **dst, void **src, size_t length)
 	*src = zalloc(length);
 	if (!*src)
 		die("memory allocation failed - maybe length is too large?\n");
-	/* Make sure to always replace the zero pages even if MMAP_THRESH is crossed */
+
+	/* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */
 	memset(*src, 0, length);
 }
 
@@ -308,8 +302,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, bool prefault)
 {
 	struct timeval tv_start, tv_end, tv_diff;
 	memcpy_t fn = r->fn.memcpy;
@@ -337,10 +330,10 @@ 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,
+		.routines		= memcpy_routines,
+		.do_cycle		= do_memcpy_cycle,
+		.do_gettimeofday	= do_memcpy_gettimeofday,
+		.usage			= bench_mem_memcpy_usage,
 	};
 
 	return bench_mem_common(argc, argv, prefix, &info);
@@ -404,30 +397,26 @@ static const char * const bench_mem_memset_usage[] = {
 };
 
 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
+	{ .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
 
-	{ .name = NULL,
-	  .desc = NULL,
-	  .fn.memset = NULL   }
+	{ 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 __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,
+		.routines		= memset_routines,
+		.do_cycle		= do_memset_cycle,
+		.do_gettimeofday	= do_memset_gettimeofday,
+		.usage			= bench_mem_memset_usage,
 	};
 
 	return bench_mem_common(argc, argv, prefix, &info);
Signature · 1 line
2.1.4
#2 lore raw

[tip:perf/core] perf bench: Improve the 'perf bench mem memcpy' code readability

perf bench: Improve the 'perf bench mem memcpy' code readability
Commit-ID:  13839ec495a31844d66d487f740c07771c60a0d0
Gitweb:     http://git.kernel.org/tip/13839ec495a31844d66d487f740c07771c60a0d0
Author:     Ingo Molnar <[email protected]>
AuthorDate: Mon, 19 Oct 2015 10:04:17 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 19 Oct 2015 15:05:00 -0300

perf bench: Improve the 'perf bench mem memcpy' code readability

- improve the readability of initializations
- fix unnecessary double negations
- fix ugly line breaks
- fix other small details

---
 tools/perf/bench/mem-memcpy.c | 101 +++++++++++++++++++-----------------------
 1 file changed, 45 insertions(+), 56 deletions(-)
tools/perf/bench/mem-memcpy.c +45 -56
index d3dfb79..27606ff 100644
@@ -1,7 +1,7 @@
 /*
  * mem-memcpy.c
  *
- * memcpy: Simple memory copy in various ways
+ * Simple memcpy() and memset() benchmarks
  *
  * Written by Hitoshi Mitake <[email protected]>
  */
@@ -61,20 +61,17 @@ struct routine {
 };
 
 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
+	{ .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,
-	  NULL,
-	  {NULL}   }
+	{ NULL, }
 };
 
 static const char * const bench_mem_memcpy_usage[] = {
@@ -89,8 +86,7 @@ static struct perf_event_attr cycle_attr = {
 
 static void init_cycle(void)
 {
-	cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1,
-				       perf_event_open_cloexec_flag());
+	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");
@@ -111,12 +107,9 @@ static u64 get_cycle(void)
 
 static double timeval2double(struct timeval *ts)
 {
-	return (double)ts->tv_sec +
-		(double)ts->tv_usec / (double)1000000;
+	return (double)ts->tv_sec + (double)ts->tv_usec / (double)1000000;
 }
 
-#define pf (no_prefault ? 0 : 1)
-
 #define print_bps(x) do {					\
 		if (x < K)					\
 			printf(" %14lf B/Sec", x);		\
@@ -140,6 +133,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l
 	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;
@@ -149,8 +143,8 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l
 	if (bench_format == BENCH_FORMAT_DEFAULT)
 		printf("# Copying %s Bytes ...\n\n", length_str);
 
-	if (!only_prefault && !no_prefault) {
-		/* show both of results */
+	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);
@@ -160,14 +154,14 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l
 		}
 	} else {
 		if (use_cycle)
-			result_cycle[pf] = info->do_cycle(r, len, only_prefault);
+			result_cycle[prefault] = info->do_cycle(r, len, only_prefault);
 		else
-			result_bps[pf] = info->do_gettimeofday(r, len, only_prefault);
+			result_bps[prefault] = info->do_gettimeofday(r, len, only_prefault);
 	}
 
 	switch (bench_format) {
 	case BENCH_FORMAT_DEFAULT:
-		if (!only_prefault && !no_prefault) {
+		if (!only_prefault && prefault) {
 			if (use_cycle) {
 				printf(" %14lf Cycle/Byte\n",
 					(double)result_cycle[0]
@@ -184,16 +178,16 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l
 		} else {
 			if (use_cycle) {
 				printf(" %14lf Cycle/Byte",
-					(double)result_cycle[pf]
+					(double)result_cycle[prefault]
 					/ totallen);
 			} else
-				print_bps(result_bps[pf]);
+				print_bps(result_bps[prefault]);
 
 			printf("%s\n", only_prefault ? " (with prefault)" : "");
 		}
 		break;
 	case BENCH_FORMAT_SIMPLE:
-		if (!only_prefault && !no_prefault) {
+		if (!only_prefault && prefault) {
 			if (use_cycle) {
 				printf("%lf %lf\n",
 					(double)result_cycle[0] / totallen,
@@ -204,14 +198,14 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l
 			}
 		} else {
 			if (use_cycle) {
-				printf("%lf\n", (double)result_cycle[pf]
+				printf("%lf\n", (double)result_cycle[prefault]
 					/ totallen);
 			} else
-				printf("%lf\n", result_bps[pf]);
+				printf("%lf\n", result_bps[prefault]);
 		}
 		break;
 	default:
-		/* reaching this means there's some disaster: */
+		/* Reaching this means there's some disaster: */
 		die("unknown format: %d\n", bench_format);
 		break;
 	}
@@ -225,8 +219,7 @@ static int bench_mem_common(int argc, const char **argv,
 	size_t len;
 	double totallen;
 
-	argc = parse_options(argc, argv, options,
-			     info->usage, 0);
+	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");
@@ -244,7 +237,7 @@ static int bench_mem_common(int argc, const char **argv,
 		return 1;
 	}
 
-	/* same to without specifying either of prefault and no-prefault */
+	/* Same as without specifying either of prefault and no-prefault: */
 	if (only_prefault && no_prefault)
 		only_prefault = no_prefault = false;
 
@@ -282,7 +275,8 @@ static void memcpy_alloc_mem(void **dst, void **src, size_t length)
 	*src = zalloc(length);
 	if (!*src)
 		die("memory allocation failed - maybe length is too large?\n");
-	/* Make sure to always replace the zero pages even if MMAP_THRESH is crossed */
+
+	/* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */
 	memset(*src, 0, length);
 }
 
@@ -308,8 +302,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, bool prefault)
 {
 	struct timeval tv_start, tv_end, tv_diff;
 	memcpy_t fn = r->fn.memcpy;
@@ -337,10 +330,10 @@ 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,
+		.routines		= memcpy_routines,
+		.do_cycle		= do_memcpy_cycle,
+		.do_gettimeofday	= do_memcpy_gettimeofday,
+		.usage			= bench_mem_memcpy_usage,
 	};
 
 	return bench_mem_common(argc, argv, prefix, &info);
@@ -404,30 +397,26 @@ static const char * const bench_mem_memset_usage[] = {
 };
 
 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
+	{ .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
 
-	{ .name = NULL,
-	  .desc = NULL,
-	  .fn.memset = NULL   }
+	{ 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 __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,
+		.routines		= memset_routines,
+		.do_cycle		= do_memset_cycle,
+		.do_gettimeofday	= do_memset_gettimeofday,
+		.usage			= bench_mem_memset_usage,
 	};
 
 	return bench_mem_common(argc, argv, prefix, &info);
#3 lore raw

PATCH 2/14 perf/bench: Default to all routines in 'perf bench mem'

In reply to Ingo Molnar

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 <[email protected]>
Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 tools/perf/bench/mem-memcpy.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/bench/mem-memcpy.c +2 -2
index 27606ff5c4f9..263f84171ae5 100644
@@ -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"),
Signature · 1 line
2.1.4
#4 lore raw

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

Quoted 11 lines · Ingo Molnar
        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

#5 lore raw

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

Quoted 13 lines · Linus Torvalds
Quoted 11 lines · Ingo Molnar
        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)
Quoted 2 lines

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:

Quoted 7 lines

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

#6 lore raw

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

In reply to Ingo Molnar
perf bench: Default to all routines in 'perf bench mem'
Commit-ID:  276197415685e2a91ce367562800cf0f8fbe482c
Gitweb:     http://git.kernel.org/tip/276197415685e2a91ce367562800cf0f8fbe482c
Author:     Ingo Molnar <[email protected]>
AuthorDate: Mon, 19 Oct 2015 10:04:18 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
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)
---
 tools/perf/bench/mem-memcpy.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/bench/mem-memcpy.c +2 -2
index 27606ff..263f841 100644
@@ -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"),
#7 lore raw

PATCH 3/14 perf/bench: Eliminate unused argument from bench_mem_common()

In reply to Ingo Molnar
Cc Arnaldo Carvalho de Melo <[email protected]>
Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 tools/perf/bench/mem-memcpy.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)
tools/perf/bench/mem-memcpy.c +4 -7
index 263f84171ae5..7acb9b83382c 100644
@@ -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);
 }
Signature · 1 line
2.1.4
#8 lore raw

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

perf bench: Eliminate unused argument from bench_mem_common()
Commit-ID:  2946f59ac31d703738c00c684613d289e8d001ea
Gitweb:     http://git.kernel.org/tip/2946f59ac31d703738c00c684613d289e8d001ea
Author:     Ingo Molnar <[email protected]>
AuthorDate: Mon, 19 Oct 2015 10:04:19 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 19 Oct 2015 15:29:08 -0300

perf bench: Eliminate unused argument from bench_mem_common()

---
 tools/perf/bench/mem-memcpy.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)
tools/perf/bench/mem-memcpy.c +4 -7
index 263f841..7acb9b8 100644
@@ -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);
 }
#9 lore raw

PATCH 4/14 perf/bench: Rename 'mem-memcpy.c' => 'mem-functions.c'

In reply to Ingo Molnar

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 <[email protected]>
Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 tools/perf/bench/Build           |   2 +-
 tools/perf/bench/mem-functions.c | 420 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 421 insertions(+), 1 deletion(-)
tools/perf/bench/Build +1 -1
index 573e28896038..60bf11943047 100644
@@ -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
tools/perf/bench/mem-functions.c new file +420 -0

420 lines not on this page · raw message

Signature · 1 line
2.1.4
#10 lore raw

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

Em Mon, Oct 19, 2015 at 10:04:20AM +0200, Ingo Molnar escreveu:

Quoted 17 lines

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 <[email protected]>
Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
Quoted 3 lines
---
 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

Quoted 442 lines
 2 files changed, 421 insertions(+), 1 deletion(-)
tools/perf/bench/Build +1 -1
index 573e28896038..60bf11943047 100644
@@ -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
tools/perf/bench/mem-functions.c new file +420 -0
new file mode 100644
index 000000000000..8f91c2e6b459
@@ -0,0 +1,420 @@
+/*
+ * mem-functions.c
+ *
+ * Simple memcpy() and memset() benchmarks.
+ *
+ * Written by Hitoshi Mitake <[email protected]>
+ */
+
+#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);
+}
Signature · 1 line
2.1.4
#11 lore raw

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

Em Mon, Oct 19, 2015 at 04:35:20PM -0200, Arnaldo Carvalho de Melo escreveu:

Quoted 22 lines

Em Mon, Oct 19, 2015 at 10:04:20AM +0200, Ingo Molnar escreveu:

Quoted 17 lines

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 <[email protected]>
Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
Quoted 3 lines
---
 tools/perf/bench/Build           |   2 +-
 tools/perf/bench/mem-functions.c | 420 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Quoted 4 lines

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 <[email protected]>
  */
@@ -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,

#12 lore raw

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

In reply to Ingo Molnar
perf bench: Rename 'mem-memcpy.c' => 'mem-functions.c'
Commit-ID:  9b2fa7f3e7799a335fd839906ab4d45b7d595dc4
Gitweb:     http://git.kernel.org/tip/9b2fa7f3e7799a335fd839906ab4d45b7d595dc4
Author:     Ingo Molnar <[email protected]>
AuthorDate: Mon, 19 Oct 2015 10:04:20 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
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.

Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>

[ The "rename" was introducing __unused, wasn't removing the old file,
and didn't update tools/perf/bench/Build, fix it ]

---
 tools/perf/bench/Build                             | 2 +-
 tools/perf/bench/{mem-memcpy.c => mem-functions.c} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
tools/perf/bench/Build +1 -1
index 573e288..60bf119 100644
@@ -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
tools/perf/bench/mem-functions.c renamed from tools/perf/bench/mem-memcpy.c +0 -0
similarity index 100%
rename from tools/perf/bench/mem-memcpy.c
rename to tools/perf/bench/mem-functions.c
#13 lore raw

PATCH 5/14 perf/bench: Remove the prefaulting complication from 'perf bench mem mem*'

In reply to Ingo Molnar

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 <[email protected]>
Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 tools/perf/bench/mem-functions.c | 146 ++++++++++++++++++++---------------------------------------
 1 file changed, 50 insertions(+), 96 deletions(-)
tools/perf/bench/mem-functions.c +50 -96
index 8f91c2e6b459..33de5d57a163 100644
@@ -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)
Signature · 1 line
2.1.4
#14 lore raw

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

perf bench: Remove the prefaulting complication from 'perf bench mem mem*'
Commit-ID:  6db175c7333e22ee818373cbea067e3eaa0236f7
Gitweb:     http://git.kernel.org/tip/6db175c7333e22ee818373cbea067e3eaa0236f7
Author:     Ingo Molnar <[email protected]>
AuthorDate: Mon, 19 Oct 2015 10:04:21 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
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.

Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
[ Remove --no-prefault, --only-prefault from docs, noticed by David Ahern ]
---
 tools/perf/Documentation/perf-bench.txt |  16 ----
 tools/perf/bench/mem-functions.c        | 146 +++++++++++---------------------
 2 files changed, 50 insertions(+), 112 deletions(-)
tools/perf/Documentation/perf-bench.txt +0 -16
index ab632d9..9cb60ab 100644
@@ -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*::
tools/perf/bench/mem-functions.c +50 -96

259 lines not on this page · raw message

#15 lore raw

PATCH 6/14 perf/bench: List output formatting options on 'perf bench -h'

In reply to Ingo Molnar

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 <[email protected]>
Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 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(-)
tools/perf/bench/mem-functions.c +2 -2
index 33de5d57a163..d822ee0c6003 100644
@@ -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,
tools/perf/bench/mem-memcpy.c deleted +0 -420

420 lines not on this page · raw message

tools/perf/builtin-bench.c +1 -1
index f67934d46d40..1b585213ba5a 100644
@@ -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()
 };
Signature · 1 line
2.1.4
#16 lore raw

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

tools/perf/bench/mem-memcpy.c

Quoted 27 lines · Ingo Molnar
tools/perf/bench/mem-functions.c +2 -2
index 33de5d57a163..d822ee0c6003 100644
@@ -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,
tools/perf/bench/mem-memcpy.c deleted +0 -0
deleted file mode 100644
index 7acb9b83382c..000000000000

All of this seems like leftovers from previous patches.

#17 lore raw

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

Em Mon, Oct 19, 2015 at 07:28:56AM -0600, David Ahern escreveu:

Quoted 18 lines · Ingo Molnar
Quoted 17 lines
tools/perf/bench/mem-functions.c +1 -1
index 33de5d57a163..d822ee0c6003 100644
@@ -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, }
 };
 
Quoted 12 lines

tools/perf/bench/mem-memcpy.c

Quoted 10 lines
tools/perf/bench/mem-functions.c +1 -1
-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,
tools/perf/bench/mem-memcpy.c deleted +0 -0
deleted file mode 100644
index 7acb9b83382c..000000000000

All of this seems like leftovers from previous patches.

Right, I fixed this one at the rename point, 4/5 IIRc

#18 lore raw

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

In reply to Ingo Molnar
perf bench: List output formatting options on 'perf bench -h'
Commit-ID:  7a46a8fd13bd60584687f417cd35935965f29ae2
Gitweb:     http://git.kernel.org/tip/7a46a8fd13bd60584687f417cd35935965f29ae2
Author:     Ingo Molnar <[email protected]>
AuthorDate: Mon, 19 Oct 2015 10:04:22 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
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

Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
[ Removed leftovers from the mem-functions.c rename ]
---
 tools/perf/builtin-bench.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-bench.c +1 -1
index f67934d..1b58521 100644
@@ -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()
 };
#19 lore raw

PATCH 7/14 perf/bench/mem: Change 'cycle' to 'cycles'

In reply to Ingo Molnar

So 'perf bench mem memset/memcpy' has a CPU cycles measurement method, but calls it 'cycle' (singular) throughout the code, which makes it harder to read.

Rename all related functions, variables and options to a plural 'cycles' nomenclature.

Cc Arnaldo Carvalho de Melo <[email protected]>
Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 tools/perf/bench/mem-functions.c | 56 ++++++++++++++++++++++++++++----------------------------
 1 file changed, 28 insertions(+), 28 deletions(-)
tools/perf/bench/mem-functions.c +28 -28
index d822ee0c6003..150414de1497 100644
@@ -26,8 +26,8 @@
 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		use_cycles;
+static int		cycles_fd;
 
 static const struct option options[] = {
 	OPT_STRING('l', "length", &length_str, "1MB",
@@ -37,8 +37,8 @@ static const struct option options[] = {
 		    "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('c', "cycles", &use_cycles,
+		    "Use a cycles event instead of gettimeofday() to measure performance"),
 	OPT_END()
 };
 
@@ -78,22 +78,22 @@ static struct perf_event_attr cycle_attr = {
 	.config		= PERF_COUNT_HW_CPU_CYCLES
 };
 
-static void init_cycle(void)
+static void init_cycles(void)
 {
-	cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, perf_event_open_cloexec_flag());
+	cycles_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, perf_event_open_cloexec_flag());
 
-	if (cycle_fd < 0 && errno == ENOSYS)
+	if (cycles_fd < 0 && errno == ENOSYS)
 		die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
 	else
-		BUG_ON(cycle_fd < 0);
+		BUG_ON(cycles_fd < 0);
 }
 
-static u64 get_cycle(void)
+static u64 get_cycles(void)
 {
 	int ret;
 	u64 clk;
 
-	ret = read(cycle_fd, &clk, sizeof(u64));
+	ret = read(cycles_fd, &clk, sizeof(u64));
 	BUG_ON(ret != sizeof(u64));
 
 	return clk;
@@ -117,7 +117,7 @@ static double timeval2double(struct timeval *ts)
 
 struct bench_mem_info {
 	const struct routine *routines;
-	u64 (*do_cycle)(const struct routine *r, size_t len);
+	u64 (*do_cycles)(const struct routine *r, size_t len);
 	double (*do_gettimeofday)(const struct routine *r, size_t len);
 	const char *const *usage;
 };
@@ -126,31 +126,31 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l
 {
 	const struct routine *r = &info->routines[r_idx];
 	double result_bps = 0.0;
-	u64 result_cycle = 0;
+	u64 result_cycles = 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 (use_cycle) {
-		result_cycle = info->do_cycle(r, len);
+	if (use_cycles) {
+		result_cycles = info->do_cycles(r, len);
 	} else {
 		result_bps = info->do_gettimeofday(r, len);
 	}
 
 	switch (bench_format) {
 	case BENCH_FORMAT_DEFAULT:
-		if (use_cycle) {
-			printf(" %14lf Cycle/Byte\n", (double)result_cycle/totallen);
+		if (use_cycles) {
+			printf(" %14lf cycles/Byte\n", (double)result_cycles/totallen);
 		} else {
 			print_bps(result_bps);
 		}
 		break;
 
 	case BENCH_FORMAT_SIMPLE:
-		if (use_cycle) {
-			printf("%lf\n", (double)result_cycle/totallen);
+		if (use_cycles) {
+			printf("%lf\n", (double)result_cycles/totallen);
 		} else {
 			printf("%lf\n", result_bps);
 		}
@@ -170,8 +170,8 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *
 
 	argc = parse_options(argc, argv, options, info->usage, 0);
 
-	if (use_cycle)
-		init_cycle();
+	if (use_cycles)
+		init_cycles();
 
 	len = (size_t)perf_atoll((char *)length_str);
 	totallen = (double)len * iterations;
@@ -220,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)
+static u64 do_memcpy_cycles(const struct routine *r, size_t len)
 {
 	u64 cycle_start = 0ULL, cycle_end = 0ULL;
 	void *src = NULL, *dst = NULL;
@@ -235,10 +235,10 @@ static u64 do_memcpy_cycle(const struct routine *r, size_t len)
 	 */
 	fn(dst, src, len);
 
-	cycle_start = get_cycle();
+	cycle_start = get_cycles();
 	for (i = 0; i < iterations; ++i)
 		fn(dst, src, len);
-	cycle_end = get_cycle();
+	cycle_end = get_cycles();
 
 	free(src);
 	free(dst);
@@ -277,7 +277,7 @@ int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unu
 {
 	struct bench_mem_info info = {
 		.routines		= memcpy_routines,
-		.do_cycle		= do_memcpy_cycle,
+		.do_cycles		= do_memcpy_cycles,
 		.do_gettimeofday	= do_memcpy_gettimeofday,
 		.usage			= bench_mem_memcpy_usage,
 	};
@@ -292,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)
+static u64 do_memset_cycles(const struct routine *r, size_t len)
 {
 	u64 cycle_start = 0ULL, cycle_end = 0ULL;
 	memset_t fn = r->fn.memset;
@@ -307,10 +307,10 @@ static u64 do_memset_cycle(const struct routine *r, size_t len)
 	 */
 	fn(dst, -1, len);
 
-	cycle_start = get_cycle();
+	cycle_start = get_cycles();
 	for (i = 0; i < iterations; ++i)
 		fn(dst, i, len);
-	cycle_end = get_cycle();
+	cycle_end = get_cycles();
 
 	free(dst);
 	return cycle_end - cycle_start;
@@ -365,7 +365,7 @@ int bench_mem_memset(int argc, const char **argv, const char *prefix __maybe_unu
 {
 	struct bench_mem_info info = {
 		.routines		= memset_routines,
-		.do_cycle		= do_memset_cycle,
+		.do_cycles		= do_memset_cycles,
 		.do_gettimeofday	= do_memset_gettimeofday,
 		.usage			= bench_mem_memset_usage,
 	};
Signature · 1 line
2.1.4
#20 lore raw

[tip:perf/core] perf bench mem: Change 'cycle' to 'cycles'

perf bench mem: Change 'cycle' to 'cycles'
Commit-ID:  b14f2d357675bd7fb4e5a705ac7320a9638ecab5
Gitweb:     http://git.kernel.org/tip/b14f2d357675bd7fb4e5a705ac7320a9638ecab5
Author:     Ingo Molnar <[email protected]>
AuthorDate: Mon, 19 Oct 2015 10:04:23 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 19 Oct 2015 16:05:01 -0300

perf bench mem: Change 'cycle' to 'cycles'

So 'perf bench mem memset/memcpy' has a CPU cycles measurement method, but calls it 'cycle' (singular) throughout the code, which makes it harder to read.

Rename all related functions, variables and options to a plural 'cycles' nomenclature.

Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
[ s/--cycle/--cycles/g in perf-bench man page ]
---
 tools/perf/Documentation/perf-bench.txt |  4 +--
 tools/perf/bench/mem-functions.c        | 56 ++++++++++++++++-----------------
 2 files changed, 30 insertions(+), 30 deletions(-)
tools/perf/Documentation/perf-bench.txt +2 -2
index 9cb60ab..17135ef 100644
@@ -154,7 +154,7 @@ On x86-64, x86-64-unrolled, x86-64-movsq and x86-64-movsb are supported.
 Repeat memcpy invocation this number of times.
 
 -c::
---cycle::
+--cycles::
 Use perf's cpu-cycles event instead of gettimeofday syscall.
 
 *memset*::
@@ -178,7 +178,7 @@ On x86-64, x86-64-unrolled, x86-64-stosq and x86-64-stosb are supported.
 Repeat memset invocation this number of times.
 
 -c::
---cycle::
+--cycles::
 Use perf's cpu-cycles event instead of gettimeofday syscall.
 
 SUITES FOR 'numa'
tools/perf/bench/mem-functions.c +28 -28

160 lines not on this page · raw message

#21 lore raw

PATCH 8/14 perf/bench/mem: Rename 'routine' to 'routine_str'

In reply to Ingo Molnar

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.

Cc Arnaldo Carvalho de Melo <[email protected]>
Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 tools/perf/bench/mem-functions.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
tools/perf/bench/mem-functions.c +7 -7
index 150414de1497..fc2afd1bfb4e 100644
@@ -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,
@@ -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);
@@ -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",
Signature · 1 line
2.1.4
#22 lore raw

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

tools/perf/bench/mem-functions.c static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l · line 134

Quoted 9 lines · Ingo Molnar
tools/perf/bench/mem-functions.c +1 -1
@@ -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.

#23 lore raw

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

Em Mon, Oct 19, 2015 at 07:34:46AM -0600, David Ahern escreveu:

Quoted 5 lines · Ingo Molnar
Quoted 4 lines
tools/perf/bench/mem-functions.c +0 -0
@@ -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;
 
Quoted 7 lines

tools/perf/bench/mem-functions.c static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l · line 134

Quoted 5 lines
tools/perf/bench/mem-functions.c +1 -1
-	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.

- Arnaldo

#24 lore raw

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

Em Mon, Oct 19, 2015 at 04:54:47PM -0200, Arnaldo Carvalho de Melo escreveu:

Quoted 9 lines

Em Mon, Oct 19, 2015 at 07:34:46AM -0600, David Ahern escreveu:

Quoted 8 lines · Ingo Molnar
Quoted 7 lines
tools/perf/bench/mem-functions.c +1 -1
@@ -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);
 
Quoted 6 lines
Quoted 4 lines

tools/perf/bench/mem-functions.c static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l · line 134

Quoted 2 lines
tools/perf/bench/mem-functions.c +0 -0
 	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.

- Arnaldo

#25 lore raw

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

Quoted 10 lines · Arnaldo Carvalho de Melo

Em Mon, Oct 19, 2015 at 04:54:47PM -0200, Arnaldo Carvalho de Melo escreveu:

Quoted 9 lines

Em Mon, Oct 19, 2015 at 07:34:46AM -0600, David Ahern escreveu:

Quoted 8 lines · Ingo Molnar
Quoted 7 lines
tools/perf/bench/mem-functions.c +1 -1
@@ -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);
 
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

tools/perf/bench/mem-functions.c static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l · line 134

Quoted 2 lines
tools/perf/bench/mem-functions.c +0 -0
 	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?

Thanks,

Ingo

#26 lore raw

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

Em Mon, Oct 19, 2015 at 09:09:32PM +0200, Ingo Molnar escreveu:

Quoted 22 lines · Arnaldo Carvalho de Melo
Quoted 11 lines

Em Mon, Oct 19, 2015 at 04:54:47PM -0200, Arnaldo Carvalho de Melo escreveu:

Quoted 9 lines

Em Mon, Oct 19, 2015 at 07:34:46AM -0600, David Ahern escreveu:

Quoted 8 lines · Ingo Molnar
Quoted 7 lines
tools/perf/bench/mem-functions.c +1 -1
@@ -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);
 
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

tools/perf/bench/mem-functions.c static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l · line 134

Quoted 2 lines
tools/perf/bench/mem-functions.c +0 -0
 	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.

Quoted 8 lines

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

#27 lore raw

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

Em Mon, Oct 19, 2015 at 05:20:03PM -0200, Arnaldo Carvalho de Melo escreveu:

Quoted 16 lines

Em Mon, Oct 19, 2015 at 09:09:32PM +0200, Ingo Molnar escreveu:

Quoted 15 lines · Arnaldo Carvalho de Melo
Quoted 7 lines

Em Mon, Oct 19, 2015 at 04:54:47PM -0200, Arnaldo Carvalho de Melo escreveu:

Quoted 4 lines

Em Mon, Oct 19, 2015 at 07:34:46AM -0600, David Ahern escreveu:

Quoted 1 line

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.

Quoted 4 lines
Quoted 2 lines

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

#28 lore raw

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

Quoted 17 lines · Arnaldo Carvalho de Melo

Em Mon, Oct 19, 2015 at 05:20:03PM -0200, Arnaldo Carvalho de Melo escreveu:

Quoted 16 lines

Em Mon, Oct 19, 2015 at 09:09:32PM +0200, Ingo Molnar escreveu:

Quoted 15 lines · Arnaldo Carvalho de Melo
Quoted 7 lines

Em Mon, Oct 19, 2015 at 04:54:47PM -0200, Arnaldo Carvalho de Melo escreveu:

Quoted 4 lines

Em Mon, Oct 19, 2015 at 07:34:46AM -0600, David Ahern escreveu:

Quoted 1 line

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.

Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

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

#29 lore raw

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

In reply to Ingo Molnar
perf bench mem: Rename 'routine' to 'routine_str'
Commit-ID:  e815e327604af880bdcf38cdd711dfa78627ab2a
Gitweb:     http://git.kernel.org/tip/e815e327604af880bdcf38cdd711dfa78627ab2a
Author:     Ingo Molnar <[email protected]>
AuthorDate: Mon, 19 Oct 2015 10:04:24 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
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.

---
 tools/perf/bench/mem-functions.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
tools/perf/bench/mem-functions.c +6 -6
index 6fe8667..a76e57f 100644
@@ -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",
#30 lore raw

PATCH 9/14 perf/bench/mem: Fix 'length' vs. 'size' naming confusion

In reply to Ingo Molnar

So 'perf bench mem memcpy/memset' consistently uses 'len' and 'length' for buffer sizes - while it's really a memory buffer size. (strings have length.)

Rename all affected variables.

Cc Arnaldo Carvalho de Melo <[email protected]>
Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 tools/perf/bench/mem-functions.c | 92 ++++++++++++++++++++++++++++++------------------------------
 1 file changed, 46 insertions(+), 46 deletions(-)
tools/perf/bench/mem-functions.c +46 -46
index fc2afd1bfb4e..0cd9020b8601 100644
@@ -23,15 +23,15 @@
 
 #define K 1024
 
-static const char	*length_str	= "1MB";
+static const char	*size_str	= "1MB";
 static const char	*routine_str	= "all";
 static int		iterations	= 1;
 static bool		use_cycles;
 static int		cycles_fd;
 
 static const struct option options[] = {
-	OPT_STRING('l', "length", &length_str, "1MB",
-		    "Specify length of memory to copy. "
+	OPT_STRING('l', "size", &size_str, "1MB",
+		    "Specify the size of the memory buffers. "
 		    "Available units: B, KB, MB, GB and TB (upper and lower)"),
 	OPT_STRING('r', "routine", &routine_str, "all",
 		    "Specify the routine to run, \"all\" runs all available routines"),
@@ -117,12 +117,12 @@ static double timeval2double(struct timeval *ts)
 
 struct bench_mem_info {
 	const struct routine *routines;
-	u64 (*do_cycles)(const struct routine *r, size_t len);
-	double (*do_gettimeofday)(const struct routine *r, size_t len);
+	u64 (*do_cycles)(const struct routine *r, size_t size);
+	double (*do_gettimeofday)(const struct routine *r, size_t size);
 	const char *const *usage;
 };
 
-static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t len, double totallen)
+static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t size, double size_total)
 {
 	const struct routine *r = &info->routines[r_idx];
 	double result_bps = 0.0;
@@ -131,18 +131,18 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l
 	printf("routine %s (%s)\n", r->name, r->desc);
 
 	if (bench_format == BENCH_FORMAT_DEFAULT)
-		printf("# Copying %s Bytes ...\n\n", length_str);
+		printf("# Copying %s Bytes ...\n\n", size_str);
 
 	if (use_cycles) {
-		result_cycles = info->do_cycles(r, len);
+		result_cycles = info->do_cycles(r, size);
 	} else {
-		result_bps = info->do_gettimeofday(r, len);
+		result_bps = info->do_gettimeofday(r, size);
 	}
 
 	switch (bench_format) {
 	case BENCH_FORMAT_DEFAULT:
 		if (use_cycles) {
-			printf(" %14lf cycles/Byte\n", (double)result_cycles/totallen);
+			printf(" %14lf cycles/Byte\n", (double)result_cycles/size_total);
 		} else {
 			print_bps(result_bps);
 		}
@@ -150,7 +150,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l
 
 	case BENCH_FORMAT_SIMPLE:
 		if (use_cycles) {
-			printf("%lf\n", (double)result_cycles/totallen);
+			printf("%lf\n", (double)result_cycles/size_total);
 		} else {
 			printf("%lf\n", result_bps);
 		}
@@ -165,25 +165,25 @@ 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, struct bench_mem_info *info)
 {
 	int i;
-	size_t len;
-	double totallen;
+	size_t size;
+	double size_total;
 
 	argc = parse_options(argc, argv, options, info->usage, 0);
 
 	if (use_cycles)
 		init_cycles();
 
-	len = (size_t)perf_atoll((char *)length_str);
-	totallen = (double)len * iterations;
+	size = (size_t)perf_atoll((char *)size_str);
+	size_total = (double)size * iterations;
 
-	if ((s64)len <= 0) {
-		fprintf(stderr, "Invalid length:%s\n", length_str);
+	if ((s64)size <= 0) {
+		fprintf(stderr, "Invalid size:%s\n", size_str);
 		return 1;
 	}
 
 	if (!strncmp(routine_str, "all", 3)) {
 		for (i = 0; info->routines[i].name; i++)
-			__bench_mem_routine(info, i, len, totallen);
+			__bench_mem_routine(info, i, size, size_total);
 		return 0;
 	}
 
@@ -201,43 +201,43 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *
 		return 1;
 	}
 
-	__bench_mem_routine(info, i, len, totallen);
+	__bench_mem_routine(info, i, size, size_total);
 
 	return 0;
 }
 
-static void memcpy_alloc_mem(void **dst, void **src, size_t length)
+static void memcpy_alloc_mem(void **dst, void **src, size_t size)
 {
-	*dst = zalloc(length);
+	*dst = zalloc(size);
 	if (!*dst)
-		die("memory allocation failed - maybe length is too large?\n");
+		die("memory allocation failed - maybe size is too large?\n");
 
-	*src = zalloc(length);
+	*src = zalloc(size);
 	if (!*src)
-		die("memory allocation failed - maybe length is too large?\n");
+		die("memory allocation failed - maybe size is too large?\n");
 
 	/* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */
-	memset(*src, 0, length);
+	memset(*src, 0, size);
 }
 
-static u64 do_memcpy_cycles(const struct routine *r, size_t len)
+static u64 do_memcpy_cycles(const struct routine *r, size_t size)
 {
 	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);
+	memcpy_alloc_mem(&dst, &src, size);
 
 	/*
 	 * We prefault the freshly allocated memory range here,
 	 * to not measure page fault overhead:
 	 */
-	fn(dst, src, len);
+	fn(dst, src, size);
 
 	cycle_start = get_cycles();
 	for (i = 0; i < iterations; ++i)
-		fn(dst, src, len);
+		fn(dst, src, size);
 	cycle_end = get_cycles();
 
 	free(src);
@@ -245,24 +245,24 @@ static u64 do_memcpy_cycles(const struct routine *r, size_t len)
 	return cycle_end - cycle_start;
 }
 
-static double do_memcpy_gettimeofday(const struct routine *r, size_t len)
+static double do_memcpy_gettimeofday(const struct routine *r, size_t size)
 {
 	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);
+	memcpy_alloc_mem(&dst, &src, size);
 
 	/*
 	 * We prefault the freshly allocated memory range here,
 	 * to not measure page fault overhead:
 	 */
-	fn(dst, src, len);
+	fn(dst, src, size);
 
 	BUG_ON(gettimeofday(&tv_start, NULL));
 	for (i = 0; i < iterations; ++i)
-		fn(dst, src, len);
+		fn(dst, src, size);
 	BUG_ON(gettimeofday(&tv_end, NULL));
 
 	timersub(&tv_end, &tv_start, &tv_diff);
@@ -270,7 +270,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len)
 	free(src);
 	free(dst);
 
-	return (double)(((double)len * iterations) / timeval2double(&tv_diff));
+	return (double)(((double)size * iterations) / timeval2double(&tv_diff));
 }
 
 int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unused)
@@ -285,61 +285,61 @@ int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unu
 	return bench_mem_common(argc, argv, &info);
 }
 
-static void memset_alloc_mem(void **dst, size_t length)
+static void memset_alloc_mem(void **dst, size_t size)
 {
-	*dst = zalloc(length);
+	*dst = zalloc(size);
 	if (!*dst)
-		die("memory allocation failed - maybe length is too large?\n");
+		die("memory allocation failed - maybe size is too large?\n");
 }
 
-static u64 do_memset_cycles(const struct routine *r, size_t len)
+static u64 do_memset_cycles(const struct routine *r, size_t size)
 {
 	u64 cycle_start = 0ULL, cycle_end = 0ULL;
 	memset_t fn = r->fn.memset;
 	void *dst = NULL;
 	int i;
 
-	memset_alloc_mem(&dst, len);
+	memset_alloc_mem(&dst, size);
 
 	/*
 	 * We prefault the freshly allocated memory range here,
 	 * to not measure page fault overhead:
 	 */
-	fn(dst, -1, len);
+	fn(dst, -1, size);
 
 	cycle_start = get_cycles();
 	for (i = 0; i < iterations; ++i)
-		fn(dst, i, len);
+		fn(dst, i, size);
 	cycle_end = get_cycles();
 
 	free(dst);
 	return cycle_end - cycle_start;
 }
 
-static double do_memset_gettimeofday(const struct routine *r, size_t len)
+static double do_memset_gettimeofday(const struct routine *r, size_t size)
 {
 	struct timeval tv_start, tv_end, tv_diff;
 	memset_t fn = r->fn.memset;
 	void *dst = NULL;
 	int i;
 
-	memset_alloc_mem(&dst, len);
+	memset_alloc_mem(&dst, size);
 
 	/*
 	 * We prefault the freshly allocated memory range here,
 	 * to not measure page fault overhead:
 	 */
-	fn(dst, -1, len);
+	fn(dst, -1, size);
 
 	BUG_ON(gettimeofday(&tv_start, NULL));
 	for (i = 0; i < iterations; ++i)
-		fn(dst, i, len);
+		fn(dst, i, size);
 	BUG_ON(gettimeofday(&tv_end, NULL));
 
 	timersub(&tv_end, &tv_start, &tv_diff);
 
 	free(dst);
-	return (double)(((double)len * iterations) / timeval2double(&tv_diff));
+	return (double)(((double)size * iterations) / timeval2double(&tv_diff));
 }
 
 static const char * const bench_mem_memset_usage[] = {
Signature · 1 line
2.1.4
#31 lore raw

[tip:perf/core] perf bench mem: Fix 'length' vs. 'size' naming confusion

perf bench mem: Fix 'length' vs. 'size' naming confusion
Commit-ID:  a69b4f741340a52d0976636a45c9976a883f03a0
Gitweb:     http://git.kernel.org/tip/a69b4f741340a52d0976636a45c9976a883f03a0
Author:     Ingo Molnar <[email protected]>
AuthorDate: Mon, 19 Oct 2015 10:04:25 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 19 Oct 2015 16:07:11 -0300

perf bench mem: Fix 'length' vs. 'size' naming confusion

So 'perf bench mem memcpy/memset' consistently uses 'len' and 'length' for buffer sizes - while it's really a memory buffer size. (strings have length.)

Rename all affected variables.

Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
[ Update perf-bench man page ]
---
 tools/perf/Documentation/perf-bench.txt |  8 +--
 tools/perf/bench/mem-functions.c        | 92 ++++++++++++++++-----------------
 2 files changed, 50 insertions(+), 50 deletions(-)
tools/perf/Documentation/perf-bench.txt +4 -4
index 17135ef..bbd27d8 100644
@@ -139,8 +139,8 @@ Suite for evaluating performance of simple memory copy in various ways.
 Options of *memcpy*
 ^^^^^^^^^^^^^^^^^^^
 -l::
---length::
-Specify length of memory to copy (default: 1MB).
+--size::
+Specify size of memory to copy (default: 1MB).
 Available units are B, KB, MB, GB and TB (case insensitive).
 
 -r::
@@ -163,8 +163,8 @@ Suite for evaluating performance of simple memory set in various ways.
 Options of *memset*
 ^^^^^^^^^^^^^^^^^^^
 -l::
---length::
-Specify length of memory to set (default: 1MB).
+--size::
+Specify size of memory to set (default: 1MB).
 Available units are B, KB, MB, GB and TB (case insensitive).
 
 -r::
tools/perf/bench/mem-functions.c +46 -46

258 lines not on this page · raw message

#32 lore raw

PATCH 10/14 perf/bench/mem: Improve user visible strings

In reply to Ingo Molnar

- fix various typos in user visible output strings
- make the output consistent (wrt. capitalization and spelling)
- offer the list of routines to benchmark on '-r help'.

Cc Arnaldo Carvalho de Melo <[email protected]>
Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 tools/perf/bench/mem-functions.c | 29 +++++++++++++++++------------
 tools/perf/builtin-bench.c       |  6 +++---
 2 files changed, 20 insertions(+), 15 deletions(-)
tools/perf/bench/mem-functions.c +17 -12
index 0cd9020b8601..34faeccdce34 100644
@@ -32,13 +32,17 @@ static int		cycles_fd;
 static const struct option options[] = {
 	OPT_STRING('l', "size", &size_str, "1MB",
 		    "Specify the size of the memory buffers. "
-		    "Available units: B, KB, MB, GB and TB (upper and lower)"),
+		    "Available units: B, KB, MB, GB and TB (case insensitive)"),
+
 	OPT_STRING('r', "routine", &routine_str, "all",
-		    "Specify the routine to run, \"all\" runs all available routines"),
+		    "Specify the routine to run, \"all\" runs all available routines, \"help\" lists them"),
+
 	OPT_INTEGER('i', "iterations", &iterations,
-		    "repeat memcpy() invocation this number of times"),
+		    "Repeat the function this number of times"),
+
 	OPT_BOOLEAN('c', "cycles", &use_cycles,
 		    "Use a cycles event instead of gettimeofday() to measure performance"),
+
 	OPT_END()
 };
 
@@ -106,13 +110,13 @@ static double timeval2double(struct timeval *ts)
 
 #define print_bps(x) do {						\
 		if (x < K)						\
-			printf(" %14lf B/Sec\n", x);			\
+			printf(" %14lf bytes/sec\n", x);		\
 		else if (x < K * K)					\
-			printf(" %14lfd KB/Sec\n", x / K);		\
+			printf(" %14lfd KB/sec\n", x / K);		\
 		else if (x < K * K * K)					\
-			printf(" %14lf MB/Sec\n", x / K / K);		\
+			printf(" %14lf MB/sec\n", x / K / K);		\
 		else							\
-			printf(" %14lf GB/Sec\n", x / K / K / K);	\
+			printf(" %14lf GB/sec\n", x / K / K / K);	\
 	} while (0)
 
 struct bench_mem_info {
@@ -128,10 +132,10 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t s
 	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", size_str);
+		printf("# Copying %s bytes ...\n\n", size_str);
 
 	if (use_cycles) {
 		result_cycles = info->do_cycles(r, size);
@@ -142,7 +146,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t s
 	switch (bench_format) {
 	case BENCH_FORMAT_DEFAULT:
 		if (use_cycles) {
-			printf(" %14lf cycles/Byte\n", (double)result_cycles/size_total);
+			printf(" %14lf cycles/byte\n", (double)result_cycles/size_total);
 		} else {
 			print_bps(result_bps);
 		}
@@ -192,8 +196,9 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *
 			break;
 	}
 	if (!info->routines[i].name) {
-		printf("Unknown routine: %s\n", routine_str);
-		printf("Available routines...\n");
+		if (strcmp(routine_str, "help") && strcmp(routine_str, "h"))
+			printf("Unknown routine: %s\n", routine_str);
+		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);
tools/perf/builtin-bench.c +3 -3
index 1b585213ba5a..a8fc948c8ace 100644
@@ -49,9 +49,9 @@ static struct bench sched_benchmarks[] = {
 };
 
 static struct bench mem_benchmarks[] = {
-	{ "memcpy",	"Benchmark for memcpy()",			bench_mem_memcpy	},
-	{ "memset",	"Benchmark for memset() tests",			bench_mem_memset	},
-	{ "all",	"Test all memory benchmarks",			NULL			},
+	{ "memcpy",	"Benchmark for memcpy() functions",		bench_mem_memcpy	},
+	{ "memset",	"Benchmark for memset() functions",		bench_mem_memset	},
+	{ "all",	"Test all memory access benchmarks",		NULL			},
 	{ NULL,		NULL,						NULL			}
 };
 
Signature · 1 line
2.1.4
#33 lore raw

[tip:perf/core] perf bench mem: Improve user visible strings

perf bench mem: Improve user visible strings
Commit-ID:  13b1fdce8d46027f346c0533a4323b58e2b5bad8
Gitweb:     http://git.kernel.org/tip/13b1fdce8d46027f346c0533a4323b58e2b5bad8
Author:     Ingo Molnar <[email protected]>
AuthorDate: Mon, 19 Oct 2015 10:04:26 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 19 Oct 2015 16:07:18 -0300

perf bench mem: Improve user visible strings

- fix various typos in user visible output strings
- make the output consistent (wrt. capitalization and spelling)
- offer the list of routines to benchmark on '-r help'.

---
 tools/perf/bench/mem-functions.c | 29 +++++++++++++++++------------
 tools/perf/builtin-bench.c       |  6 +++---
 2 files changed, 20 insertions(+), 15 deletions(-)
tools/perf/bench/mem-functions.c +17 -12
index 1605249..318da34 100644
@@ -32,13 +32,17 @@ static int		cycles_fd;
 static const struct option options[] = {
 	OPT_STRING('l', "size", &size_str, "1MB",
 		    "Specify the size of the memory buffers. "
-		    "Available units: B, KB, MB, GB and TB (upper and lower)"),
+		    "Available units: B, KB, MB, GB and TB (case insensitive)"),
+
 	OPT_STRING('r', "routine", &routine_str, "all",
-		    "Specify the routine to run, \"all\" runs all available routines"),
+		    "Specify the routine to run, \"all\" runs all available routines, \"help\" lists them"),
+
 	OPT_INTEGER('i', "iterations", &iterations,
-		    "repeat memcpy() invocation this number of times"),
+		    "Repeat the function this number of times"),
+
 	OPT_BOOLEAN('c', "cycles", &use_cycles,
 		    "Use a cycles event instead of gettimeofday() to measure performance"),
+
 	OPT_END()
 };
 
@@ -106,13 +110,13 @@ static double timeval2double(struct timeval *ts)
 
 #define print_bps(x) do {						\
 		if (x < K)						\
-			printf(" %14lf B/Sec\n", x);			\
+			printf(" %14lf bytes/sec\n", x);		\
 		else if (x < K * K)					\
-			printf(" %14lfd KB/Sec\n", x / K);		\
+			printf(" %14lfd KB/sec\n", x / K);		\
 		else if (x < K * K * K)					\
-			printf(" %14lf MB/Sec\n", x / K / K);		\
+			printf(" %14lf MB/sec\n", x / K / K);		\
 		else							\
-			printf(" %14lf GB/Sec\n", x / K / K / K);	\
+			printf(" %14lf GB/sec\n", x / K / K / K);	\
 	} while (0)
 
 struct bench_mem_info {
@@ -128,10 +132,10 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t s
 	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", size_str);
+		printf("# Copying %s bytes ...\n\n", size_str);
 
 	if (use_cycles) {
 		result_cycles = info->do_cycles(r, size);
@@ -142,7 +146,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t s
 	switch (bench_format) {
 	case BENCH_FORMAT_DEFAULT:
 		if (use_cycles) {
-			printf(" %14lf cycles/Byte\n", (double)result_cycles/size_total);
+			printf(" %14lf cycles/byte\n", (double)result_cycles/size_total);
 		} else {
 			print_bps(result_bps);
 		}
@@ -192,8 +196,9 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *
 			break;
 	}
 	if (!info->routines[i].name) {
-		printf("Unknown routine: %s\n", routine_str);
-		printf("Available routines...\n");
+		if (strcmp(routine_str, "help") && strcmp(routine_str, "h"))
+			printf("Unknown routine: %s\n", routine_str);
+		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);
tools/perf/builtin-bench.c +3 -3
index 1b58521..a8fc948 100644
@@ -49,9 +49,9 @@ static struct bench sched_benchmarks[] = {
 };
 
 static struct bench mem_benchmarks[] = {
-	{ "memcpy",	"Benchmark for memcpy()",			bench_mem_memcpy	},
-	{ "memset",	"Benchmark for memset() tests",			bench_mem_memset	},
-	{ "all",	"Test all memory benchmarks",			NULL			},
+	{ "memcpy",	"Benchmark for memcpy() functions",		bench_mem_memcpy	},
+	{ "memset",	"Benchmark for memset() functions",		bench_mem_memset	},
+	{ "all",	"Test all memory access benchmarks",		NULL			},
 	{ NULL,		NULL,						NULL			}
 };
 
#34 lore raw

PATCH 11/14 perf/bench/mem: Reorganize the code a bit

In reply to Ingo Molnar

Reorder functions a bit, so that we synchronize the layout of the memcpy() and memset() portions of the code.

This improves the code, especially after we'll add an strlcpy() variant as well.

Cc Arnaldo Carvalho de Melo <[email protected]>
Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 tools/perf/bench/mem-functions.c | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)
tools/perf/bench/mem-functions.c +19 -19
index 34faeccdce34..f701b5b56079 100644
@@ -58,25 +58,6 @@ struct routine {
 	} 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
@@ -278,6 +259,25 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t size)
 	return (double)(((double)size * iterations) / timeval2double(&tv_diff));
 }
 
+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
+};
+
 int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unused)
 {
 	struct bench_mem_info info = {
Signature · 1 line
2.1.4
#35 lore raw

[tip:perf/core] perf bench mem: Reorganize the code a bit

perf bench mem: Reorganize the code a bit
Commit-ID:  5dd93304a5d386c73c0a59117752acdca67f857d
Gitweb:     http://git.kernel.org/tip/5dd93304a5d386c73c0a59117752acdca67f857d
Author:     Ingo Molnar <[email protected]>
AuthorDate: Mon, 19 Oct 2015 10:04:27 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 19 Oct 2015 16:07:19 -0300

perf bench mem: Reorganize the code a bit

Reorder functions a bit, so that we synchronize the layout of the memcpy() and memset() portions of the code.

This improves the code, especially after we'll add an strlcpy() variant as well.

---
 tools/perf/bench/mem-functions.c | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)
tools/perf/bench/mem-functions.c +19 -19
index 318da34..8d980d4 100644
@@ -58,25 +58,6 @@ struct routine {
 	} 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
@@ -278,6 +259,25 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t size)
 	return (double)(((double)size * iterations) / timeval2double(&tv_diff));
 }
 
+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
+};
+
 int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unused)
 {
 	struct bench_mem_info info = {
#36 lore raw

PATCH 12/14 perf/bench: Harmonize all the -l/--nr_loops options

In reply to Ingo Molnar

We have three benchmarking subsystems that specify some sort of 'number of loops' parameter - but all of them do it inconsistently:

numa: -l/--nr_loops
sched messaging: -l/--loops
mem memset/memcpy: -i/--iterations

Harmonize them to -l/--nr_loops by picking the numa variant - which is also the most likely one to have existing scripting which we don't want to break.

Plus improve the parameter help texts to indicate the default value for the nr_loops variable to keep users from guessing ...

Also propagate the naming to internal variables.

Cc Arnaldo Carvalho de Melo <[email protected]>
Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 tools/perf/bench/mem-functions.c   | 22 +++++++++++-----------
 tools/perf/bench/numa.c            |  4 ++--
 tools/perf/bench/sched-messaging.c | 10 +++++-----
 3 files changed, 18 insertions(+), 18 deletions(-)
tools/perf/bench/mem-functions.c +11 -11
index f701b5b56079..65e7297de4b1 100644
@@ -25,20 +25,20 @@
 
 static const char	*size_str	= "1MB";
 static const char	*routine_str	= "all";
-static int		iterations	= 1;
+static int		nr_loops	= 1;
 static bool		use_cycles;
 static int		cycles_fd;
 
 static const struct option options[] = {
-	OPT_STRING('l', "size", &size_str, "1MB",
+	OPT_STRING('s', "size", &size_str, "1MB",
 		    "Specify the size of the memory buffers. "
 		    "Available units: B, KB, MB, GB and TB (case insensitive)"),
 
 	OPT_STRING('r', "routine", &routine_str, "all",
 		    "Specify the routine to run, \"all\" runs all available routines, \"help\" lists them"),
 
-	OPT_INTEGER('i', "iterations", &iterations,
-		    "Repeat the function this number of times"),
+	OPT_INTEGER('l', "nr_loops", &nr_loops,
+		    "Specify the number of loops to run. (default: 1)"),
 
 	OPT_BOOLEAN('c', "cycles", &use_cycles,
 		    "Use a cycles event instead of gettimeofday() to measure performance"),
@@ -159,7 +159,7 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *
 		init_cycles();
 
 	size = (size_t)perf_atoll((char *)size_str);
-	size_total = (double)size * iterations;
+	size_total = (double)size * nr_loops;
 
 	if ((s64)size <= 0) {
 		fprintf(stderr, "Invalid size:%s\n", size_str);
@@ -222,7 +222,7 @@ static u64 do_memcpy_cycles(const struct routine *r, size_t size)
 	fn(dst, src, size);
 
 	cycle_start = get_cycles();
-	for (i = 0; i < iterations; ++i)
+	for (i = 0; i < nr_loops; ++i)
 		fn(dst, src, size);
 	cycle_end = get_cycles();
 
@@ -247,7 +247,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t size)
 	fn(dst, src, size);
 
 	BUG_ON(gettimeofday(&tv_start, NULL));
-	for (i = 0; i < iterations; ++i)
+	for (i = 0; i < nr_loops; ++i)
 		fn(dst, src, size);
 	BUG_ON(gettimeofday(&tv_end, NULL));
 
@@ -256,7 +256,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t size)
 	free(src);
 	free(dst);
 
-	return (double)(((double)size * iterations) / timeval2double(&tv_diff));
+	return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
 }
 
 struct routine memcpy_routines[] = {
@@ -313,7 +313,7 @@ static u64 do_memset_cycles(const struct routine *r, size_t size)
 	fn(dst, -1, size);
 
 	cycle_start = get_cycles();
-	for (i = 0; i < iterations; ++i)
+	for (i = 0; i < nr_loops; ++i)
 		fn(dst, i, size);
 	cycle_end = get_cycles();
 
@@ -337,14 +337,14 @@ static double do_memset_gettimeofday(const struct routine *r, size_t size)
 	fn(dst, -1, size);
 
 	BUG_ON(gettimeofday(&tv_start, NULL));
-	for (i = 0; i < iterations; ++i)
+	for (i = 0; i < nr_loops; ++i)
 		fn(dst, i, size);
 	BUG_ON(gettimeofday(&tv_end, NULL));
 
 	timersub(&tv_end, &tv_start, &tv_diff);
 
 	free(dst);
-	return (double)(((double)size * iterations) / timeval2double(&tv_diff));
+	return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
 }
 
 static const char * const bench_mem_memset_usage[] = {
tools/perf/bench/numa.c +2 -2
index 870b7e665a20..492df2752a2d 100644
@@ -164,8 +164,8 @@ static const struct option options[] = {
 	OPT_STRING('L', "mb_proc_locked", &p0.mb_proc_locked_str,"MB", "process serialized/locked memory access (MBs), <= process_memory"),
 	OPT_STRING('T', "mb_thread"	, &p0.mb_thread_str,	"MB", "thread  memory (MBs)"),
 
-	OPT_UINTEGER('l', "nr_loops"	, &p0.nr_loops,		"max number of loops to run"),
-	OPT_UINTEGER('s', "nr_secs"	, &p0.nr_secs,		"max number of seconds to run"),
+	OPT_UINTEGER('l', "nr_loops"	, &p0.nr_loops,		"max number of loops to run (default: unlimited)"),
+	OPT_UINTEGER('s', "nr_secs"	, &p0.nr_secs,		"max number of seconds to run (default: 5 secs)"),
 	OPT_UINTEGER('u', "usleep"	, &p0.sleep_usecs,	"usecs to sleep per loop iteration"),
 
 	OPT_BOOLEAN('R', "data_reads"	, &p0.data_reads,	"access the data via writes (can be mixed with -W)"),
tools/perf/bench/sched-messaging.c +5 -5
index d7f281c2828d..d4ff1b539cfd 100644
@@ -33,7 +33,7 @@
 #define DATASIZE 100
 
 static bool use_pipes = false;
-static unsigned int loops = 100;
+static unsigned int nr_loops = 100;
 static bool thread_mode = false;
 static unsigned int num_groups = 10;
 
@@ -79,7 +79,7 @@ static void ready(int ready_out, int wakefd)
 		err(EXIT_FAILURE, "poll");
 }
 
-/* Sender sprays loops messages down each file descriptor */
+/* Sender sprays nr_loops messages down each file descriptor */
 static void *sender(struct sender_context *ctx)
 {
 	char data[DATASIZE];
@@ -88,7 +88,7 @@ static void *sender(struct sender_context *ctx)
 	ready(ctx->ready_out, ctx->wakefd);
 
 	/* Now pump to every receiver. */
-	for (i = 0; i < loops; i++) {
+	for (i = 0; i < nr_loops; i++) {
 		for (j = 0; j < ctx->num_fds; j++) {
 			int ret, done = 0;
 
@@ -213,7 +213,7 @@ static unsigned int group(pthread_t *pth,
 		/* Create the pipe between client and server */
 		fdpair(fds);
 
-		ctx->num_packets = num_fds * loops;
+		ctx->num_packets = num_fds * nr_loops;
 		ctx->in_fds[0] = fds[0];
 		ctx->in_fds[1] = fds[1];
 		ctx->ready_out = ready_out;
@@ -250,7 +250,7 @@ static const struct option options[] = {
 	OPT_BOOLEAN('t', "thread", &thread_mode,
 		    "Be multi thread instead of multi process"),
 	OPT_UINTEGER('g', "group", &num_groups, "Specify number of groups"),
-	OPT_UINTEGER('l', "loop", &loops, "Specify number of loops"),
+	OPT_UINTEGER('l', "nr_loops", &nr_loops, "Specify the number of loops to run (default: 100)"),
 	OPT_END()
 };
 
Signature · 1 line
2.1.4
#37 lore raw

[tip:perf/core] perf bench: Harmonize all the -l/ --nr_loops options

perf bench: Harmonize all the -l/--nr_loops options
Commit-ID:  b0d22e52e3d2c2b151dfaa0f6e01bafa5475344f
Gitweb:     http://git.kernel.org/tip/b0d22e52e3d2c2b151dfaa0f6e01bafa5475344f
Author:     Ingo Molnar <[email protected]>
AuthorDate: Mon, 19 Oct 2015 10:04:28 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 19 Oct 2015 16:10:05 -0300

perf bench: Harmonize all the -l/--nr_loops options

We have three benchmarking subsystems that specify some sort of 'number of loops' parameter - but all of them do it inconsistently:

numa: -l/--nr_loops
sched messaging: -l/--loops
mem memset/memcpy: -i/--iterations

Harmonize them to -l/--nr_loops by picking the numa variant - which is also the most likely one to have existing scripting which we don't want to break.

Plus improve the parameter help texts to indicate the default value for the nr_loops variable to keep users from guessing ...

Also propagate the naming to internal variables.

Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
[ Let the harmonisation reach the perf-bench man page as well ]
---
 tools/perf/Documentation/perf-bench.txt | 10 +++++-----
 tools/perf/bench/mem-functions.c        | 22 +++++++++++-----------
 tools/perf/bench/numa.c                 |  4 ++--
 tools/perf/bench/sched-messaging.c      | 10 +++++-----
 4 files changed, 23 insertions(+), 23 deletions(-)
tools/perf/Documentation/perf-bench.txt +5 -5
index bbd27d8..ddfb3e1 100644
@@ -82,7 +82,7 @@ Be multi thread instead of multi process
 Specify number of groups
 
 -l::
---loop=::
+--nr_loops=::
 Specify number of loops
 
 Example of *messaging*
@@ -149,8 +149,8 @@ Specify routine to copy (default: default).
 Available routines are depend on the architecture.
 On x86-64, x86-64-unrolled, x86-64-movsq and x86-64-movsb are supported.
 
--i::
---iterations::
+-l::
+--nr_loops::
 Repeat memcpy invocation this number of times.
 
 -c::
@@ -173,8 +173,8 @@ Specify routine to set (default: default).
 Available routines are depend on the architecture.
 On x86-64, x86-64-unrolled, x86-64-stosq and x86-64-stosb are supported.
 
--i::
---iterations::
+-l::
+--nr_loops::
 Repeat memset invocation this number of times.
 
 -c::
tools/perf/bench/mem-functions.c +11 -11
index 8d980d4..c5dfabd 100644
@@ -25,20 +25,20 @@
 
 static const char	*size_str	= "1MB";
 static const char	*routine_str	= "all";
-static int		iterations	= 1;
+static int		nr_loops	= 1;
 static bool		use_cycles;
 static int		cycles_fd;
 
 static const struct option options[] = {
-	OPT_STRING('l', "size", &size_str, "1MB",
+	OPT_STRING('s', "size", &size_str, "1MB",
 		    "Specify the size of the memory buffers. "
 		    "Available units: B, KB, MB, GB and TB (case insensitive)"),
 
 	OPT_STRING('r', "routine", &routine_str, "all",
 		    "Specify the routine to run, \"all\" runs all available routines, \"help\" lists them"),
 
-	OPT_INTEGER('i', "iterations", &iterations,
-		    "Repeat the function this number of times"),
+	OPT_INTEGER('l', "nr_loops", &nr_loops,
+		    "Specify the number of loops to run. (default: 1)"),
 
 	OPT_BOOLEAN('c', "cycles", &use_cycles,
 		    "Use a cycles event instead of gettimeofday() to measure performance"),
@@ -159,7 +159,7 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *
 		init_cycles();
 
 	size = (size_t)perf_atoll((char *)size_str);
-	size_total = (double)size * iterations;
+	size_total = (double)size * nr_loops;
 
 	if ((s64)size <= 0) {
 		fprintf(stderr, "Invalid size:%s\n", size_str);
@@ -222,7 +222,7 @@ static u64 do_memcpy_cycles(const struct routine *r, size_t size)
 	fn(dst, src, size);
 
 	cycle_start = get_cycles();
-	for (i = 0; i < iterations; ++i)
+	for (i = 0; i < nr_loops; ++i)
 		fn(dst, src, size);
 	cycle_end = get_cycles();
 
@@ -247,7 +247,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t size)
 	fn(dst, src, size);
 
 	BUG_ON(gettimeofday(&tv_start, NULL));
-	for (i = 0; i < iterations; ++i)
+	for (i = 0; i < nr_loops; ++i)
 		fn(dst, src, size);
 	BUG_ON(gettimeofday(&tv_end, NULL));
 
@@ -256,7 +256,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t size)
 	free(src);
 	free(dst);
 
-	return (double)(((double)size * iterations) / timeval2double(&tv_diff));
+	return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
 }
 
 struct routine memcpy_routines[] = {
@@ -313,7 +313,7 @@ static u64 do_memset_cycles(const struct routine *r, size_t size)
 	fn(dst, -1, size);
 
 	cycle_start = get_cycles();
-	for (i = 0; i < iterations; ++i)
+	for (i = 0; i < nr_loops; ++i)
 		fn(dst, i, size);
 	cycle_end = get_cycles();
 
@@ -337,14 +337,14 @@ static double do_memset_gettimeofday(const struct routine *r, size_t size)
 	fn(dst, -1, size);
 
 	BUG_ON(gettimeofday(&tv_start, NULL));
-	for (i = 0; i < iterations; ++i)
+	for (i = 0; i < nr_loops; ++i)
 		fn(dst, i, size);
 	BUG_ON(gettimeofday(&tv_end, NULL));
 
 	timersub(&tv_end, &tv_start, &tv_diff);
 
 	free(dst);
-	return (double)(((double)size * iterations) / timeval2double(&tv_diff));
+	return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
 }
 
 static const char * const bench_mem_memset_usage[] = {
tools/perf/bench/numa.c +2 -2
index 870b7e6..492df27 100644
@@ -164,8 +164,8 @@ static const struct option options[] = {
 	OPT_STRING('L', "mb_proc_locked", &p0.mb_proc_locked_str,"MB", "process serialized/locked memory access (MBs), <= process_memory"),
 	OPT_STRING('T', "mb_thread"	, &p0.mb_thread_str,	"MB", "thread  memory (MBs)"),
 
-	OPT_UINTEGER('l', "nr_loops"	, &p0.nr_loops,		"max number of loops to run"),
-	OPT_UINTEGER('s', "nr_secs"	, &p0.nr_secs,		"max number of seconds to run"),
+	OPT_UINTEGER('l', "nr_loops"	, &p0.nr_loops,		"max number of loops to run (default: unlimited)"),
+	OPT_UINTEGER('s', "nr_secs"	, &p0.nr_secs,		"max number of seconds to run (default: 5 secs)"),
 	OPT_UINTEGER('u', "usleep"	, &p0.sleep_usecs,	"usecs to sleep per loop iteration"),
 
 	OPT_BOOLEAN('R', "data_reads"	, &p0.data_reads,	"access the data via writes (can be mixed with -W)"),
tools/perf/bench/sched-messaging.c +5 -5
index d7f281c..d4ff1b5 100644
@@ -33,7 +33,7 @@
 #define DATASIZE 100
 
 static bool use_pipes = false;
-static unsigned int loops = 100;
+static unsigned int nr_loops = 100;
 static bool thread_mode = false;
 static unsigned int num_groups = 10;
 
@@ -79,7 +79,7 @@ static void ready(int ready_out, int wakefd)
 		err(EXIT_FAILURE, "poll");
 }
 
-/* Sender sprays loops messages down each file descriptor */
+/* Sender sprays nr_loops messages down each file descriptor */
 static void *sender(struct sender_context *ctx)
 {
 	char data[DATASIZE];
@@ -88,7 +88,7 @@ static void *sender(struct sender_context *ctx)
 	ready(ctx->ready_out, ctx->wakefd);
 
 	/* Now pump to every receiver. */
-	for (i = 0; i < loops; i++) {
+	for (i = 0; i < nr_loops; i++) {
 		for (j = 0; j < ctx->num_fds; j++) {
 			int ret, done = 0;
 
@@ -213,7 +213,7 @@ static unsigned int group(pthread_t *pth,
 		/* Create the pipe between client and server */
 		fdpair(fds);
 
-		ctx->num_packets = num_fds * loops;
+		ctx->num_packets = num_fds * nr_loops;
 		ctx->in_fds[0] = fds[0];
 		ctx->in_fds[1] = fds[1];
 		ctx->ready_out = ready_out;
@@ -250,7 +250,7 @@ static const struct option options[] = {
 	OPT_BOOLEAN('t', "thread", &thread_mode,
 		    "Be multi thread instead of multi process"),
 	OPT_UINTEGER('g', "group", &num_groups, "Specify number of groups"),
-	OPT_UINTEGER('l', "loop", &loops, "Specify number of loops"),
+	OPT_UINTEGER('l', "nr_loops", &nr_loops, "Specify the number of loops to run (default: 100)"),
 	OPT_END()
 };
 
#38 lore raw

PATCH 13/14 perf/bench/mem: Rename 'routine' to 'function'

In reply to Ingo Molnar

So right now there's a somewhat inconsistent mess of the benchmarking code and options sometimes calling benchmarked functions 'functions', sometimes calling them 'routines'.

Name them 'functions' consistently.

Cc Arnaldo Carvalho de Melo <[email protected]>
Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 tools/perf/bench/mem-functions.c | 60 ++++++++++++++++++++++++++++++------------------------------
 1 file changed, 30 insertions(+), 30 deletions(-)
tools/perf/bench/mem-functions.c +30 -30
index 65e7297de4b1..d8fc59092b39 100644
@@ -24,7 +24,7 @@
 #define K 1024
 
 static const char	*size_str	= "1MB";
-static const char	*routine_str	= "all";
+static const char	*function_str	= "all";
 static int		nr_loops	= 1;
 static bool		use_cycles;
 static int		cycles_fd;
@@ -34,8 +34,8 @@ static const struct option options[] = {
 		    "Specify the size of the memory buffers. "
 		    "Available units: B, KB, MB, GB and TB (case insensitive)"),
 
-	OPT_STRING('r', "routine", &routine_str, "all",
-		    "Specify the routine to run, \"all\" runs all available routines, \"help\" lists them"),
+	OPT_STRING('f', "function", &function_str, "all",
+		    "Specify the function to run, \"all\" runs all available functions, \"help\" lists them"),
 
 	OPT_INTEGER('l', "nr_loops", &nr_loops,
 		    "Specify the number of loops to run. (default: 1)"),
@@ -49,7 +49,7 @@ static const struct option options[] = {
 typedef void *(*memcpy_t)(void *, const void *, size_t);
 typedef void *(*memset_t)(void *, int, size_t);
 
-struct routine {
+struct function {
 	const char *name;
 	const char *desc;
 	union {
@@ -101,19 +101,19 @@ static double timeval2double(struct timeval *ts)
 	} while (0)
 
 struct bench_mem_info {
-	const struct routine *routines;
-	u64 (*do_cycles)(const struct routine *r, size_t size);
-	double (*do_gettimeofday)(const struct routine *r, size_t size);
+	const struct function *functions;
+	u64 (*do_cycles)(const struct function *r, size_t size);
+	double (*do_gettimeofday)(const struct function *r, size_t size);
 	const char *const *usage;
 };
 
-static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t size, double size_total)
+static void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t size, double size_total)
 {
-	const struct routine *r = &info->routines[r_idx];
+	const struct function *r = &info->functions[r_idx];
 	double result_bps = 0.0;
 	u64 result_cycles = 0;
 
-	printf("# Routine '%s' (%s)\n", r->name, r->desc);
+	printf("# function '%s' (%s)\n", r->name, r->desc);
 
 	if (bench_format == BENCH_FORMAT_DEFAULT)
 		printf("# Copying %s bytes ...\n\n", size_str);
@@ -166,28 +166,28 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *
 		return 1;
 	}
 
-	if (!strncmp(routine_str, "all", 3)) {
-		for (i = 0; info->routines[i].name; i++)
-			__bench_mem_routine(info, i, size, size_total);
+	if (!strncmp(function_str, "all", 3)) {
+		for (i = 0; info->functions[i].name; i++)
+			__bench_mem_function(info, i, size, size_total);
 		return 0;
 	}
 
-	for (i = 0; info->routines[i].name; i++) {
-		if (!strcmp(info->routines[i].name, routine_str))
+	for (i = 0; info->functions[i].name; i++) {
+		if (!strcmp(info->functions[i].name, function_str))
 			break;
 	}
-	if (!info->routines[i].name) {
-		if (strcmp(routine_str, "help") && strcmp(routine_str, "h"))
-			printf("Unknown routine: %s\n", routine_str);
-		printf("Available routines:\n");
-		for (i = 0; info->routines[i].name; i++) {
+	if (!info->functions[i].name) {
+		if (strcmp(function_str, "help") && strcmp(function_str, "h"))
+			printf("Unknown function: %s\n", function_str);
+		printf("Available functions:\n");
+		for (i = 0; info->functions[i].name; i++) {
 			printf("\t%s ... %s\n",
-			       info->routines[i].name, info->routines[i].desc);
+			       info->functions[i].name, info->functions[i].desc);
 		}
 		return 1;
 	}
 
-	__bench_mem_routine(info, i, size, size_total);
+	__bench_mem_function(info, i, size, size_total);
 
 	return 0;
 }
@@ -206,7 +206,7 @@ static void memcpy_alloc_mem(void **dst, void **src, size_t size)
 	memset(*src, 0, size);
 }
 
-static u64 do_memcpy_cycles(const struct routine *r, size_t size)
+static u64 do_memcpy_cycles(const struct function *r, size_t size)
 {
 	u64 cycle_start = 0ULL, cycle_end = 0ULL;
 	void *src = NULL, *dst = NULL;
@@ -231,7 +231,7 @@ static u64 do_memcpy_cycles(const struct routine *r, size_t size)
 	return cycle_end - cycle_start;
 }
 
-static double do_memcpy_gettimeofday(const struct routine *r, size_t size)
+static double do_memcpy_gettimeofday(const struct function *r, size_t size)
 {
 	struct timeval tv_start, tv_end, tv_diff;
 	memcpy_t fn = r->fn.memcpy;
@@ -259,7 +259,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t size)
 	return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
 }
 
-struct routine memcpy_routines[] = {
+struct function memcpy_functions[] = {
 	{ .name		= "default",
 	  .desc		= "Default memcpy() provided by glibc",
 	  .fn.memcpy	= memcpy },
@@ -281,7 +281,7 @@ static const char * const bench_mem_memcpy_usage[] = {
 int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unused)
 {
 	struct bench_mem_info info = {
-		.routines		= memcpy_routines,
+		.functions		= memcpy_functions,
 		.do_cycles		= do_memcpy_cycles,
 		.do_gettimeofday	= do_memcpy_gettimeofday,
 		.usage			= bench_mem_memcpy_usage,
@@ -297,7 +297,7 @@ static void memset_alloc_mem(void **dst, size_t size)
 		die("memory allocation failed - maybe size is too large?\n");
 }
 
-static u64 do_memset_cycles(const struct routine *r, size_t size)
+static u64 do_memset_cycles(const struct function *r, size_t size)
 {
 	u64 cycle_start = 0ULL, cycle_end = 0ULL;
 	memset_t fn = r->fn.memset;
@@ -321,7 +321,7 @@ static u64 do_memset_cycles(const struct routine *r, size_t size)
 	return cycle_end - cycle_start;
 }
 
-static double do_memset_gettimeofday(const struct routine *r, size_t size)
+static double do_memset_gettimeofday(const struct function *r, size_t size)
 {
 	struct timeval tv_start, tv_end, tv_diff;
 	memset_t fn = r->fn.memset;
@@ -352,7 +352,7 @@ static const char * const bench_mem_memset_usage[] = {
 	NULL
 };
 
-static const struct routine memset_routines[] = {
+static const struct function memset_functions[] = {
 	{ .name		= "default",
 	  .desc		= "Default memset() provided by glibc",
 	  .fn.memset	= memset },
@@ -369,7 +369,7 @@ static const struct routine memset_routines[] = {
 int bench_mem_memset(int argc, const char **argv, const char *prefix __maybe_unused)
 {
 	struct bench_mem_info info = {
-		.routines		= memset_routines,
+		.functions		= memset_functions,
 		.do_cycles		= do_memset_cycles,
 		.do_gettimeofday	= do_memset_gettimeofday,
 		.usage			= bench_mem_memset_usage,
Signature · 1 line
2.1.4
#39 lore raw

[tip:perf/core] perf bench mem: Rename 'routine' to 'function'

perf bench mem: Rename 'routine' to 'function'
Commit-ID:  2f211c84ad40469c15226e899b720624fbd28e20
Gitweb:     http://git.kernel.org/tip/2f211c84ad40469c15226e899b720624fbd28e20
Author:     Ingo Molnar <[email protected]>
AuthorDate: Mon, 19 Oct 2015 10:04:29 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 19 Oct 2015 16:10:25 -0300

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

So right now there's a somewhat inconsistent mess of the benchmarking code and options sometimes calling benchmarked functions 'functions', sometimes calling them 'routines'.

Name them 'functions' consistently.

Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
[ Updated perf-bench man page, pointed out by David Ahern ]
---
 tools/perf/Documentation/perf-bench.txt | 16 ++++-----
 tools/perf/bench/mem-functions.c        | 60 ++++++++++++++++-----------------
 2 files changed, 38 insertions(+), 38 deletions(-)
tools/perf/Documentation/perf-bench.txt +8 -8
index ddfb3e1..34750fc 100644
@@ -143,10 +143,10 @@ Options of *memcpy*
 Specify size of memory to copy (default: 1MB).
 Available units are B, KB, MB, GB and TB (case insensitive).
 
--r::
---routine::
-Specify routine to copy (default: default).
-Available routines are depend on the architecture.
+-f::
+--function::
+Specify function to copy (default: default).
+Available functions are depend on the architecture.
 On x86-64, x86-64-unrolled, x86-64-movsq and x86-64-movsb are supported.
 
 -l::
@@ -167,10 +167,10 @@ Options of *memset*
 Specify size of memory to set (default: 1MB).
 Available units are B, KB, MB, GB and TB (case insensitive).
 
--r::
---routine::
-Specify routine to set (default: default).
-Available routines are depend on the architecture.
+-f::
+--function::
+Specify function to set (default: default).
+Available functions are depend on the architecture.
 On x86-64, x86-64-unrolled, x86-64-stosq and x86-64-stosb are supported.
 
 -l::
tools/perf/bench/mem-functions.c +30 -30

155 lines not on this page · raw message

#40 lore raw

PATCH 14/14 perf/bench: Run benchmarks, don't test them

In reply to Ingo Molnar

So right now we output this text:

memcpy: Benchmark for memcpy() functions
memset: Benchmark for memset() functions
all: Test all memory access benchmarks

But the right verb to use with benchmarks is to 'run' them, not 'test' them.

So change this (and all similar texts) to:

memcpy: Benchmark for memcpy() functions
memset: Benchmark for memset() functions
all: Run all memory access benchmarks

Cc Arnaldo Carvalho de Melo <[email protected]>
Cc David Ahern <[email protected]>
Cc Hitoshi Mitake <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 tools/perf/builtin-bench.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
tools/perf/builtin-bench.c +4 -4
index a8fc948c8ace..b17aed36ca16 100644
@@ -36,7 +36,7 @@ struct bench {
 #ifdef HAVE_LIBNUMA_SUPPORT
 static struct bench numa_benchmarks[] = {
 	{ "mem",	"Benchmark for NUMA workloads",			bench_numa		},
-	{ "all",	"Test all NUMA benchmarks",			NULL			},
+	{ "all",	"Run all NUMA benchmarks",			NULL			},
 	{ NULL,		NULL,						NULL			}
 };
 #endif
@@ -44,14 +44,14 @@ static struct bench numa_benchmarks[] = {
 static struct bench sched_benchmarks[] = {
 	{ "messaging",	"Benchmark for scheduling and IPC",		bench_sched_messaging	},
 	{ "pipe",	"Benchmark for pipe() between two processes",	bench_sched_pipe	},
-	{ "all",	"Test all scheduler benchmarks",		NULL			},
+	{ "all",	"Run all scheduler benchmarks",		NULL			},
 	{ NULL,		NULL,						NULL			}
 };
 
 static struct bench mem_benchmarks[] = {
 	{ "memcpy",	"Benchmark for memcpy() functions",		bench_mem_memcpy	},
 	{ "memset",	"Benchmark for memset() functions",		bench_mem_memset	},
-	{ "all",	"Test all memory access benchmarks",		NULL			},
+	{ "all",	"Run all memory access benchmarks",		NULL			},
 	{ NULL,		NULL,						NULL			}
 };
 
@@ -62,7 +62,7 @@ static struct bench futex_benchmarks[] = {
 	{ "requeue",	"Benchmark for futex requeue calls",            bench_futex_requeue	},
 	/* pi-futexes */
 	{ "lock-pi",	"Benchmark for futex lock_pi calls",            bench_futex_lock_pi	},
-	{ "all",	"Test all futex benchmarks",			NULL			},
+	{ "all",	"Run all futex benchmarks",			NULL			},
 	{ NULL,		NULL,						NULL			}
 };
 
Signature · 1 line
2.1.4
#41 lore raw

[tip:perf/core] perf bench: Run benchmarks, don't test them

perf bench: Run benchmarks, don't test them
Commit-ID:  aa254af25c40d6d1cdc3f354db29eaf3e85a5ede
Gitweb:     http://git.kernel.org/tip/aa254af25c40d6d1cdc3f354db29eaf3e85a5ede
Author:     Ingo Molnar <[email protected]>
AuthorDate: Mon, 19 Oct 2015 10:04:30 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 19 Oct 2015 16:10:25 -0300

perf bench: Run benchmarks, don't test them

So right now we output this text:

memcpy: Benchmark for memcpy() functions
memset: Benchmark for memset() functions
all: Test all memory access benchmarks

But the right verb to use with benchmarks is to 'run' them, not 'test' them.

So change this (and all similar texts) to:

memcpy: Benchmark for memcpy() functions
memset: Benchmark for memset() functions
all: Run all memory access benchmarks

---
 tools/perf/builtin-bench.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
tools/perf/builtin-bench.c +4 -4
index a8fc948..b17aed3 100644
@@ -36,7 +36,7 @@ struct bench {
 #ifdef HAVE_LIBNUMA_SUPPORT
 static struct bench numa_benchmarks[] = {
 	{ "mem",	"Benchmark for NUMA workloads",			bench_numa		},
-	{ "all",	"Test all NUMA benchmarks",			NULL			},
+	{ "all",	"Run all NUMA benchmarks",			NULL			},
 	{ NULL,		NULL,						NULL			}
 };
 #endif
@@ -44,14 +44,14 @@ static struct bench numa_benchmarks[] = {
 static struct bench sched_benchmarks[] = {
 	{ "messaging",	"Benchmark for scheduling and IPC",		bench_sched_messaging	},
 	{ "pipe",	"Benchmark for pipe() between two processes",	bench_sched_pipe	},
-	{ "all",	"Test all scheduler benchmarks",		NULL			},
+	{ "all",	"Run all scheduler benchmarks",		NULL			},
 	{ NULL,		NULL,						NULL			}
 };
 
 static struct bench mem_benchmarks[] = {
 	{ "memcpy",	"Benchmark for memcpy() functions",		bench_mem_memcpy	},
 	{ "memset",	"Benchmark for memset() functions",		bench_mem_memset	},
-	{ "all",	"Test all memory access benchmarks",		NULL			},
+	{ "all",	"Run all memory access benchmarks",		NULL			},
 	{ NULL,		NULL,						NULL			}
 };
 
@@ -62,7 +62,7 @@ static struct bench futex_benchmarks[] = {
 	{ "requeue",	"Benchmark for futex requeue calls",            bench_futex_requeue	},
 	/* pi-futexes */
 	{ "lock-pi",	"Benchmark for futex lock_pi calls",            bench_futex_lock_pi	},
-	{ "all",	"Test all futex benchmarks",			NULL			},
+	{ "all",	"Run all futex benchmarks",			NULL			},
 	{ NULL,		NULL,						NULL			}
 };
 
#42 lore raw
In reply to Ingo Molnar
Quoted 10 lines · Ingo Molnar
  tools/perf/bench/Build             |   2 +-
  tools/perf/bench/mem-functions.c   | 379 +++++++++++++++++++++++++++++++++++++++++++++++++
  tools/perf/bench/mem-memcpy.c      | 434 ---------------------------------------------------------
  tools/perf/bench/numa.c            |   4 +-
  tools/perf/bench/sched-messaging.c |  10 +-
  tools/perf/builtin-bench.c         |  14 +-
  6 files changed, 394 insertions(+), 449 deletions(-)

create mode 100644 tools/perf/bench/mem-functions.c delete mode 100644 tools/perf/bench/mem-memcpy.c

tools/perf/Documentation needs updating for the user visible options.

#43 lore raw

Em Mon, Oct 19, 2015 at 07:40:36AM -0600, David Ahern escreveu:

Quoted 13 lines · Ingo Molnar
Quoted 11 lines
 tools/perf/bench/Build             |   2 +-
 tools/perf/bench/mem-functions.c   | 379 +++++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/bench/mem-memcpy.c      | 434 ---------------------------------------------------------
 tools/perf/bench/numa.c            |   4 +-
 tools/perf/bench/sched-messaging.c |  10 +-
 tools/perf/builtin-bench.c         |  14 +-
 6 files changed, 394 insertions(+), 449 deletions(-)
 create mode 100644 tools/perf/bench/mem-functions.c
 delete mode 100644 tools/perf/bench/mem-memcpy.c
Quoted 1 line

tools/perf/Documentation needs updating for the user visible options.

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

changes -r to -f, fixed. Looking at the others...