Add --enable-large-benchtests for large data benchmarks
diff mbox

Message ID 20160403204905.GA24627@intel.com
State New
Headers show

Commit Message

H.J. Lu April 3, 2016, 8:49 p.m. UTC
We like to run memcpy memmove and memset benchmarks with large data sizes.
This patch adds --enable-large-benchtests to enable benchmarks with very
large data.

Tested on x86-64.  OK for master?

H.J.
---
	* benchtests/Makefile (string-benchset): Add memcpy-large,
	memmove-large and memset-large for --enable-large-benchtests.
	* benchtests/bench-memcpy-large.c: New file.
	* benchtests/bench-memmove-large.c: Likewise.
	* benchtests/bench-memmove-large.c: Likewise.
	* benchtests/bench-string.h (TIMEOUT): Don't redefine.
	* config.make.in (run-large-benchtests): New.
	* configure.ac: Add --enable-large-benchtests.
	* configure: Regenerated.
---
 benchtests/Makefile              |   3 ++
 benchtests/bench-memcpy-large.c  | 105 +++++++++++++++++++++++++++++++++++++++
 benchtests/bench-memmove-large.c | 103 ++++++++++++++++++++++++++++++++++++++
 benchtests/bench-memset-large.c  | 103 ++++++++++++++++++++++++++++++++++++++
 benchtests/bench-string.h        |   4 +-
 config.make.in                   |   1 +
 configure                        |  13 +++++
 configure.ac                     |   7 +++
 8 files changed, 338 insertions(+), 1 deletion(-)
 create mode 100644 benchtests/bench-memcpy-large.c
 create mode 100644 benchtests/bench-memmove-large.c
 create mode 100644 benchtests/bench-memset-large.c

Patch
diff mbox

diff --git a/benchtests/Makefile b/benchtests/Makefile
index a37d666..7f8ae02 100644
--- a/benchtests/Makefile
+++ b/benchtests/Makefile
@@ -39,6 +39,9 @@  string-benchset := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \
 		   strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \
 		   strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok \
 		   strcoll
+ifeq (yes,$(run-large-benchtests))
+string-benchset += memcpy-large memmove-large memset-large
+endif
 wcsmbs-benchset := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat \
 		   wcscmp wcsncmp wcschr wcschrnul wcsrchr wcsspn wcspbrk wcscspn \
 		   wmemchr wmemset wmemcmp
diff --git a/benchtests/bench-memcpy-large.c b/benchtests/bench-memcpy-large.c
new file mode 100644
index 0000000..470000f
--- /dev/null
+++ b/benchtests/bench-memcpy-large.c
@@ -0,0 +1,105 @@ 
+/* Measure memcpy functions with large data sizes.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef MEMCPY_RESULT
+# define MEMCPY_RESULT(dst, len) dst
+# define BASE_PAGE_SIZE (1024 * 1024)
+# define MIN_PAGE_SIZE (getpagesize () + 256 * BASE_PAGE_SIZE)
+# define TEST_MAIN
+# define TEST_NAME "memcpy"
+# define TIMEOUT (20 * 60)
+# include "bench-string.h"
+
+IMPL (memcpy, 1)
+#endif
+
+typedef char *(*proto_t) (char *, const char *, size_t);
+
+static void
+do_one_test (impl_t *impl, char *dst, const char *src,
+	     size_t len)
+{
+  size_t i, iters = 16;
+  timing_t start, stop, cur;
+
+  /* It is too slow to check result with a simple implementation.  */
+
+  TIMING_NOW (start);
+  for (i = 0; i < iters; ++i)
+    {
+      CALL (impl, dst, src, len);
+    }
+  TIMING_NOW (stop);
+
+  TIMING_DIFF (cur, start, stop);
+
+  TIMING_PRINT_MEAN ((double) cur, (double) iters);
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len)
+{
+  size_t i, j;
+  char *s1, *s2;
+
+  align1 &= 63;
+  if (align1 + len >= page_size)
+    return;
+
+  align2 &= 63;
+  if (align2 + len >= page_size)
+    return;
+
+  s1 = (char *) (buf1 + align1);
+  s2 = (char *) (buf2 + align2);
+
+  for (i = 0, j = 1; i < len; i++, j += 23)
+    s1[i] = j;
+
+  printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s2, s1, len);
+
+  putchar ('\n');
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%23s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = BASE_PAGE_SIZE; i <= MIN_PAGE_SIZE; i <<= 1)
+    {
+      do_test (0, 0, i);
+      do_test (0, 1, i);
+      do_test (1, 0, i);
+      do_test (1, 1, i);
+    }
+
+  return ret;
+}
+
+#include "../test-skeleton.c"
diff --git a/benchtests/bench-memmove-large.c b/benchtests/bench-memmove-large.c
new file mode 100644
index 0000000..585b94b
--- /dev/null
+++ b/benchtests/bench-memmove-large.c
@@ -0,0 +1,103 @@ 
+/* Measure memmove functions with large data sizes.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define BASE_PAGE_SIZE (1024 * 1024)
+#define MIN_PAGE_SIZE (getpagesize () + 256 * BASE_PAGE_SIZE)
+#define TEST_MAIN
+#define TEST_NAME "memmove"
+#define TIMEOUT (20 * 60)
+#include "bench-string.h"
+
+IMPL (memmove, 1)
+
+typedef char *(*proto_t) (char *, const char *, size_t);
+
+static void
+do_one_test (impl_t *impl, char *dst, char *src, const char *orig_src,
+	     size_t len)
+{
+  size_t i, iters = 16;
+  timing_t start, stop, cur;
+
+  /* It is too slow to check result with a simple implementation.  */
+
+  TIMING_NOW (start);
+  for (i = 0; i < iters; ++i)
+    {
+      CALL (impl, dst, src, len);
+    }
+  TIMING_NOW (stop);
+
+  TIMING_DIFF (cur, start, stop);
+
+  TIMING_PRINT_MEAN ((double) cur, (double) iters);
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len)
+{
+  size_t i, j;
+  char *s1, *s2;
+
+  align1 &= 127;
+  if (align1 + len >= page_size)
+    return;
+
+  align2 &= 127;
+  if (align2 + len >= page_size)
+    return;
+
+  s1 = (char *) (buf1 + align1);
+  s2 = (char *) (buf2 + align2);
+
+  for (i = 0, j = 1; i < len; i++, j += 23)
+    s1[i] = j;
+
+  printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s2, (char *) (buf2 + align1), s1, len);
+
+  putchar ('\n');
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%23s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = BASE_PAGE_SIZE; i <= MIN_PAGE_SIZE; i <<= 1)
+    {
+      do_test (0, 64, i);
+      do_test (0, 1, i);
+      do_test (1, 0, i);
+      do_test (1, 2, i);
+      do_test (6, 3, i);
+    }
+
+  return ret;
+}
+
+#include "../test-skeleton.c"
diff --git a/benchtests/bench-memset-large.c b/benchtests/bench-memset-large.c
new file mode 100644
index 0000000..acb920e
--- /dev/null
+++ b/benchtests/bench-memset-large.c
@@ -0,0 +1,103 @@ 
+/* Measure memset functions with large data sizes.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#ifndef WIDE
+# define TEST_NAME "memset"
+#else
+# define TEST_NAME "wmemset"
+#endif /* WIDE */
+#define BASE_PAGE_SIZE (1024 * 1024)
+#define MIN_PAGE_SIZE (getpagesize () + 256 * BASE_PAGE_SIZE)
+#define TIMEOUT (20 * 60)
+#include "bench-string.h"
+
+#ifndef WIDE
+# define MEMSET memset
+# define CHAR char
+# define MEMCMP memcmp
+#else
+# include <wchar.h>
+# define MEMSET wmemset
+# define CHAR wchar_t
+# define MEMCMP wmemcmp
+#endif /* WIDE */
+
+IMPL (MEMSET, 1)
+
+typedef CHAR *(*proto_t) (CHAR *, int, size_t);
+
+static void
+do_one_test (impl_t *impl, CHAR *s, int c __attribute ((unused)), size_t n)
+{
+  size_t i, iters = 16;
+  timing_t start, stop, cur;
+
+  /* It is too slow to check result with a simple implementation.  */
+
+  TIMING_NOW (start);
+  for (i = 0; i < iters; ++i)
+    {
+      CALL (impl, s, c, n);
+    }
+  TIMING_NOW (stop);
+
+  TIMING_DIFF (cur, start, stop);
+
+  TIMING_PRINT_MEAN ((double) cur, (double) iters);
+}
+
+static void
+do_test (size_t align, int c, size_t len)
+{
+  align &= 63;
+  if ((align + len) * sizeof (CHAR) > page_size)
+    return;
+
+  printf ("Length %4zd, alignment %2zd, c %2d:", len, align, c);
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, (CHAR *) (buf1) + align, c, len);
+
+  putchar ('\n');
+}
+
+int
+test_main (void)
+{
+  size_t i;
+  int c;
+
+  test_init ();
+
+  printf ("%24s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  c = 65;
+  for (i = BASE_PAGE_SIZE; i <= MIN_PAGE_SIZE; i <<= 1)
+    {
+      do_test (0, c, i);
+      do_test (1, c, i);
+    }
+
+  return ret;
+}
+
+#include "../test-skeleton.c"
diff --git a/benchtests/bench-string.h b/benchtests/bench-string.h
index be4c618..9c5371e 100644
--- a/benchtests/bench-string.h
+++ b/benchtests/bench-string.h
@@ -56,7 +56,9 @@  extern impl_t __start_impls[], __stop_impls[];
 
 
 # define TEST_FUNCTION test_main ()
-# define TIMEOUT (4 * 60)
+# ifndef TIMEOUT
+#  define TIMEOUT (4 * 60)
+# endif
 # define OPT_ITERATIONS 10000
 # define OPT_RANDOM 10001
 # define OPT_SEED 10002
diff --git a/config.make.in b/config.make.in
index 95c6f36..b9a4dbb 100644
--- a/config.make.in
+++ b/config.make.in
@@ -89,6 +89,7 @@  link-obsolete-rpc = @link_obsolete_rpc@
 build-nscd = @build_nscd@
 use-nscd = @use_nscd@
 build-hardcoded-path-in-tests= @hardcoded_path_in_tests@
+run-large-benchtests = @large_benchtests@
 build-pt-chown = @build_pt_chown@
 enable-lock-elision = @enable_lock_elision@
 
diff --git a/configure b/configure
index 8fe5937..42bde65 100755
--- a/configure
+++ b/configure
@@ -668,6 +668,7 @@  all_warnings
 force_install
 bindnow
 enable_lock_elision
+large_benchtests
 hardcoded_path_in_tests
 enable_timezone_tools
 use_default_link
@@ -755,6 +756,7 @@  enable_shared
 enable_profile
 enable_timezone_tools
 enable_hardcoded_path_in_tests
+enable_large_benchtests
 enable_stackguard_randomization
 enable_lock_elision
 enable_add_ons
@@ -1411,6 +1413,8 @@  Optional Features:
   --enable-hardcoded-path-in-tests
                           hardcode newly built glibc path in tests
                           [default=no]
+  --enable-large-benchtests
+                          run benchtests with large data size [default=no]
   --enable-stackguard-randomization
                           initialize __stack_chk_guard canary with a random
                           number at program start
@@ -3363,6 +3367,15 @@  fi
 
 
 
+# Check whether --enable-large-benchtests was given.
+if test "${enable_large_benchtests+set}" = set; then :
+  enableval=$enable_large_benchtests; large_benchtests=$enableval
+else
+  large_benchtests=no
+fi
+
+
+
 # Check whether --enable-stackguard-randomization was given.
 if test "${enable_stackguard_randomization+set}" = set; then :
   enableval=$enable_stackguard_randomization; enable_stackguard_randomize=$enableval
diff --git a/configure.ac b/configure.ac
index 3c766b7..8fb93d9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -190,6 +190,13 @@  AC_ARG_ENABLE([hardcoded-path-in-tests],
 	      [hardcoded_path_in_tests=no])
 AC_SUBST(hardcoded_path_in_tests)
 
+AC_ARG_ENABLE([large-benchtests],
+	      AC_HELP_STRING([--enable-large-benchtests],
+			     [run benchtests with large data size @<:@default=no@:>@]),
+	      [large_benchtests=$enableval],
+	      [large_benchtests=no])
+AC_SUBST(large_benchtests)
+
 AC_ARG_ENABLE([stackguard-randomization],
 	      AC_HELP_STRING([--enable-stackguard-randomization],
 			     [initialize __stack_chk_guard canary with a random number at program start]),