This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] Consolidate cmp benchtests.
- From: OndÅej BÃlka <neleai at seznam dot cz>
- To: libc-alpha at sourceware dot org
- Date: Fri, 6 Sep 2013 10:58:38 +0200
- Subject: [PATCH] Consolidate cmp benchtests.
- Authentication-results: sourceware.org; auth=none
Hi,
Same idea with cmp functions.
Again we would need to select more representative inputs as followup.
For strcasecmp we shuold also check inputs consisting of aA to stress
case where conversion is needed.
* benchtests/bench-cmp.h: New file.
* benchtests/bench-memcmp.c: Use benchtests/bench-cmp.h.
* benchtests/bench-strcasecmp.c: Likewise.
* benchtests/bench-strcmp.c: Likewise.
* benchtests/bench-strncasecmp.c: Likewise.
* benchtests/bench-strncmp.c: Likewise.
---
benchtests/bench-cmp.h | 112 ++++++++++++++++++++
benchtests/bench-memcmp.c | 159 +---------------------------
benchtests/bench-strcasecmp.c | 158 +---------------------------
benchtests/bench-strcmp.c | 225 ++--------------------------------------
benchtests/bench-strncasecmp.c | 189 +--------------------------------
benchtests/bench-strncmp.c | 221 +--------------------------------------
6 files changed, 138 insertions(+), 926 deletions(-)
create mode 100644 benchtests/bench-cmp.h
diff --git a/benchtests/bench-cmp.h b/benchtests/bench-cmp.h
new file mode 100644
index 0000000..510020e
--- /dev/null
+++ b/benchtests/bench-cmp.h
@@ -0,0 +1,112 @@
+/* Measure memcmp, strcmp, strncmp, ... functions.
+ Copyright (C) 2013 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 MEMCPY_RESULT(dst, len) dst
+#define MIN_PAGE_SIZE (1<<22)
+#define TEST_MAIN
+#include "bench-string.h"
+
+PROTO
+IMPLS
+
+static void
+do_one_test (impl_t *impl, size_t aligned, size_t len)
+{
+ size_t i, iters = INNER_LOOP_ITERS;
+ timing_t start, stop, cur;
+ static unsigned int r_seed = 42;
+
+ char *dsts[INNER_LOOP_ITERS], *srcs[INNER_LOOP_ITERS];
+ for (i = 0; i < iters; ++i)
+ {
+ srcs[i] = ((char *) buf1) + rand_r (&r_seed)%(MIN_PAGE_SIZE/2);
+ dsts[i] = ((char *) buf2) + rand_r (&r_seed)%(MIN_PAGE_SIZE/2);
+ if (aligned) /* Align pointers. */
+ {
+ srcs[i] = srcs[i] - ((uintptr_t)srcs[i])%64;
+ dsts[i] = dsts[i] - ((uintptr_t)dsts[i])%64;
+ }
+ }
+
+ TIMING_NOW (start);
+ for (i = 0; i < iters; ++i)
+ {
+ srcs[i][len] = 0;
+ CALL2 (impl, dsts[i], srcs[i], len);
+ srcs[i][len] = 1;
+ }
+ TIMING_NOW (stop);
+
+ TIMING_DIFF (cur, start, stop);
+
+ TIMING_PRINT_MEAN ((double) cur, (double) iters);
+}
+
+static void
+do_test (size_t aligned, size_t len)
+{
+ printf ("Length %4zd, aligned %c:", len, aligned ? 'y' : 'n' );
+
+ FOR_EACH_IMPL (impl, 0)
+ do_one_test (impl, aligned, len);
+
+ putchar ('\n');
+}
+
+int
+test_main (void)
+{
+ size_t i;
+
+ test_init ();
+
+ memset (buf1, 1, MIN_PAGE_SIZE);
+ memset (buf2, 1, MIN_PAGE_SIZE);
+
+#ifdef TEST_OVERLAP
+ buf1 = buf2;
+#endif
+
+ printf ("%23s", "");
+ FOR_EACH_IMPL (impl, 0)
+ printf ("\t%10s", impl->name);
+ putchar ('\n');
+
+ for (i = 0; i < 18; ++i)
+ {
+ do_test (0, 1 << i);
+ do_test (1, 1 << i);
+ }
+
+ for (i = 0; i < 32; ++i)
+ {
+ do_test (0, i);
+ do_test (1, i);
+ }
+
+ for (i = 3; i < 32; ++i)
+ {
+ do_test (0, 16 * i);
+ do_test (1, 16 * i);
+ }
+
+
+ return ret;
+}
+
+#include "../test-skeleton.c"
diff --git a/benchtests/bench-memcmp.c b/benchtests/bench-memcmp.c
index 544130b..40921bd 100644
--- a/benchtests/bench-memcmp.c
+++ b/benchtests/bench-memcmp.c
@@ -16,162 +16,13 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#define TEST_MAIN
-#ifdef WIDE
-# define TEST_NAME "wmemcmp"
-#else
-# define TEST_NAME "memcmp"
-#endif
-#include "bench-string.h"
-#ifdef WIDE
-# include <inttypes.h>
-# include <wchar.h>
-
-# define MEMCMP wmemcmp
-# define MEMCPY wmemcpy
-# define SIMPLE_MEMCMP simple_wmemcmp
-# define CHAR wchar_t
-# define UCHAR wchar_t
-# define CHARBYTES 4
-# define CHAR__MIN WCHAR_MIN
-# define CHAR__MAX WCHAR_MAX
-int
-simple_wmemcmp (const wchar_t *s1, const wchar_t *s2, size_t n)
-{
- int ret = 0;
- /* Warning!
- wmemcmp has to use SIGNED comparison for elements.
- memcmp has to use UNSIGNED comparison for elemnts.
- */
- while (n-- && (ret = *s1 < *s2 ? -1 : *s1 == *s2 ? 0 : 1) == 0) {s1++; s2++;}
- return ret;
-}
-#else
-# include <limits.h>
-
-# define MEMCMP memcmp
-# define MEMCPY memcpy
-# define SIMPLE_MEMCMP simple_memcmp
-# define CHAR char
-# define MAX_CHAR 255
-# define UCHAR unsigned char
-# define CHARBYTES 1
-# define CHAR__MIN CHAR_MIN
-# define CHAR__MAX CHAR_MAX
-
-int
-simple_memcmp (const char *s1, const char *s2, size_t n)
-{
- int ret = 0;
-
- while (n-- && (ret = *(unsigned char *) s1++ - *(unsigned char *) s2++) == 0);
- return ret;
-}
-#endif
-
-typedef int (*proto_t) (const CHAR *, const CHAR *, size_t);
-
-IMPL (SIMPLE_MEMCMP, 0)
-IMPL (MEMCMP, 1)
-
-static void
-do_one_test (impl_t *impl, const CHAR *s1, const CHAR *s2, size_t len,
- int exp_result)
-{
- size_t i, iters = INNER_LOOP_ITERS;
- timing_t start, stop, cur;
-
- TIMING_NOW (start);
- for (i = 0; i < iters; ++i)
- {
- CALL (impl, s1, s2, 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, int exp_result)
-{
- size_t i;
- CHAR *s1, *s2;
-
- if (len == 0)
- return;
- align1 &= 63;
- if (align1 + (len + 1) * CHARBYTES >= page_size)
- return;
-
- align2 &= 63;
- if (align2 + (len + 1) * CHARBYTES >= page_size)
- return;
-
- s1 = (CHAR *) (buf1 + align1);
- s2 = (CHAR *) (buf2 + align2);
-
- for (i = 0; i < len; i++)
- s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % CHAR__MAX;
-
- s1[len] = align1;
- s2[len] = align2;
- s2[len - 1] -= exp_result;
-
- printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
-
- FOR_EACH_IMPL (impl, 0)
- do_one_test (impl, s1, s2, len, exp_result);
-
- 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 = 1; i < 16; ++i)
- {
- do_test (i * CHARBYTES, i * CHARBYTES, i, 0);
- do_test (i * CHARBYTES, i * CHARBYTES, i, 1);
- do_test (i * CHARBYTES, i * CHARBYTES, i, -1);
- }
+# define TEST_NAME "memcmp"
- for (i = 0; i < 16; ++i)
- {
- do_test (0, 0, i, 0);
- do_test (0, 0, i, 1);
- do_test (0, 0, i, -1);
- }
+#define PROTO typedef char *(*proto_t) (char *, const char *, size_t);
+#define IMPLS IMPL (memcmp, 1)
- for (i = 1; i < 10; ++i)
- {
- do_test (0, 0, 2 << i, 0);
- do_test (0, 0, 2 << i, 1);
- do_test (0, 0, 2 << i, -1);
- do_test (0, 0, 16 << i, 0);
- do_test ((8 - i) * CHARBYTES, (2 * i) * CHARBYTES, 16 << i, 0);
- do_test (0, 0, 16 << i, 1);
- do_test (0, 0, 16 << i, -1);
- }
- for (i = 1; i < 8; ++i)
- {
- do_test (i * CHARBYTES, 2 * (i * CHARBYTES), 8 << i, 0);
- do_test (i * CHARBYTES, 2 * (i * CHARBYTES), 8 << i, 1);
- do_test (i * CHARBYTES, 2 * (i * CHARBYTES), 8 << i, -1);
- }
+#define CALL2(impl, dst, src, len) CALL (impl, dst, src, len)
- return ret;
-}
-#include "../test-skeleton.c"
+#include "bench-cmp.h"
diff --git a/benchtests/bench-strcasecmp.c b/benchtests/bench-strcasecmp.c
index 1458df1..b1aacb3 100644
--- a/benchtests/bench-strcasecmp.c
+++ b/benchtests/bench-strcasecmp.c
@@ -16,161 +16,13 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <ctype.h>
-#define TEST_MAIN
-#define TEST_NAME "strcasecmp"
-#include "bench-string.h"
-typedef int (*proto_t) (const char *, const char *);
-static int simple_strcasecmp (const char *, const char *);
-static int stupid_strcasecmp (const char *, const char *);
+# define TEST_NAME "strcasecmp"
-IMPL (stupid_strcasecmp, 0)
-IMPL (simple_strcasecmp, 0)
-IMPL (strcasecmp, 1)
+#define PROTO typedef char *(*proto_t) (char *, const char *);
+#define IMPLS IMPL (strcasecmp, 1)
-static int
-simple_strcasecmp (const char *s1, const char *s2)
-{
- int ret;
- while ((ret = ((unsigned char) tolower (*s1)
- - (unsigned char) tolower (*s2))) == 0
- && *s1++)
- ++s2;
- return ret;
-}
+#define CALL2(impl, dst, src, len) CALL (impl, dst, src)
-static int
-stupid_strcasecmp (const char *s1, const char *s2)
-{
- size_t ns1 = strlen (s1) + 1, ns2 = strlen (s2) + 1;
- size_t n = ns1 < ns2 ? ns1 : ns2;
- int ret = 0;
-
- while (n--)
- {
- if ((ret = ((unsigned char) tolower (*s1)
- - (unsigned char) tolower (*s2))) != 0)
- break;
- ++s1;
- ++s2;
- }
- return ret;
-}
-
-static void
-do_one_test (impl_t *impl, const char *s1, const char *s2, int exp_result)
-{
- size_t i, iters = INNER_LOOP_ITERS;
- timing_t start, stop, cur;
- int result = CALL (impl, s1, s2);
- if ((exp_result == 0 && result != 0)
- || (exp_result < 0 && result >= 0)
- || (exp_result > 0 && result <= 0))
- {
- error (0, 0, "Wrong result in function %s %d %d", impl->name,
- result, exp_result);
- ret = 1;
- return;
- }
-
- TIMING_NOW (start);
- for (i = 0; i < iters; ++i)
- {
- CALL (impl, s1, s2);
- }
- 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, int max_char,
- int exp_result)
-{
- size_t i;
- char *s1, *s2;
-
- if (len == 0)
- return;
-
- align1 &= 7;
- if (align1 + len + 1 >= page_size)
- return;
-
- align2 &= 7;
- if (align2 + len + 1 >= page_size)
- return;
-
- s1 = (char *) (buf1 + align1);
- s2 = (char *) (buf2 + align2);
-
- for (i = 0; i < len; i++)
- {
- s1[i] = toupper (1 + 23 * i % max_char);
- s2[i] = tolower (s1[i]);
- }
-
- s1[len] = s2[len] = 0;
- s1[len + 1] = 23;
- s2[len + 1] = 24 + exp_result;
- if ((s2[len - 1] == 'z' && exp_result == -1)
- || (s2[len - 1] == 'a' && exp_result == 1))
- s1[len - 1] += exp_result;
- else
- s2[len - 1] -= exp_result;
-
- printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
-
- FOR_EACH_IMPL (impl, 0)
- do_one_test (impl, s1, s2, exp_result);
-
- 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 = 1; i < 16; ++i)
- {
- do_test (i, i, i, 127, 0);
- do_test (i, i, i, 127, 1);
- do_test (i, i, i, 127, -1);
- }
-
- for (i = 1; i < 10; ++i)
- {
- do_test (0, 0, 2 << i, 127, 0);
- do_test (0, 0, 2 << i, 254, 0);
- do_test (0, 0, 2 << i, 127, 1);
- do_test (0, 0, 2 << i, 254, 1);
- do_test (0, 0, 2 << i, 127, -1);
- do_test (0, 0, 2 << i, 254, -1);
- }
-
- for (i = 1; i < 8; ++i)
- {
- do_test (i, 2 * i, 8 << i, 127, 0);
- do_test (2 * i, i, 8 << i, 254, 0);
- do_test (i, 2 * i, 8 << i, 127, 1);
- do_test (2 * i, i, 8 << i, 254, 1);
- do_test (i, 2 * i, 8 << i, 127, -1);
- do_test (2 * i, i, 8 << i, 254, -1);
- }
-
- return ret;
-}
-
-#include "../test-skeleton.c"
+#include "bench-cmp.h"
diff --git a/benchtests/bench-strcmp.c b/benchtests/bench-strcmp.c
index c1e0b26..a03f272 100644
--- a/benchtests/bench-strcmp.c
+++ b/benchtests/bench-strcmp.c
@@ -1,4 +1,4 @@
-/* Measure strcmp and wcscmp functions.
+/* Measure strcmp functions.
Copyright (C) 2013 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -16,226 +16,13 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#define TEST_MAIN
-#ifdef WIDE
-# define TEST_NAME "wcscmp"
-#else
-# define TEST_NAME "strcmp"
-#endif
-#include "bench-string.h"
-
-#ifdef WIDE
-# include <wchar.h>
-
-# define L(str) L##str
-# define STRCMP wcscmp
-# define STRCPY wcscpy
-# define STRLEN wcslen
-# define MEMCPY wmemcpy
-# define SIMPLE_STRCMP simple_wcscmp
-# define STUPID_STRCMP stupid_wcscmp
-# define CHAR wchar_t
-# define UCHAR wchar_t
-# define CHARBYTES 4
-# define CHARBYTESLOG 2
-# define CHARALIGN __alignof__ (CHAR)
-# define MIDCHAR 0x7fffffff
-# define LARGECHAR 0xfffffffe
-# define CHAR__MAX WCHAR_MAX
-# define CHAR__MIN WCHAR_MIN
-
-/* Wcscmp uses signed semantics for comparison, not unsigned */
-/* Avoid using substraction since possible overflow */
-
-int
-simple_wcscmp (const wchar_t *s1, const wchar_t *s2)
-{
- wchar_t c1, c2;
- do
- {
- c1 = *s1++;
- c2 = *s2++;
- if (c2 == L'\0')
- return c1 - c2;
- }
- while (c1 == c2);
-
- return c1 < c2 ? -1 : 1;
-}
-
-int
-stupid_wcscmp (const wchar_t *s1, const wchar_t *s2)
-{
- size_t ns1 = wcslen (s1) + 1;
- size_t ns2 = wcslen (s2) + 1;
- size_t n = ns1 < ns2 ? ns1 : ns2;
- int ret = 0;
-
- wchar_t c1, c2;
-
- while (n--) {
- c1 = *s1++;
- c2 = *s2++;
- if ((ret = c1 < c2 ? -1 : c1 == c2 ? 0 : 1) != 0)
- break;
- }
- return ret;
-}
-
-#else
-# include <limits.h>
-
-# define L(str) str
-# define STRCMP strcmp
-# define STRCPY strcpy
-# define STRLEN strlen
-# define MEMCPY memcpy
-# define SIMPLE_STRCMP simple_strcmp
-# define STUPID_STRCMP stupid_strcmp
-# define CHAR char
-# define UCHAR unsigned char
-# define CHARBYTES 1
-# define CHARBYTESLOG 0
-# define CHARALIGN 1
-# define MIDCHAR 0x7f
-# define LARGECHAR 0xfe
-# define CHAR__MAX CHAR_MAX
-# define CHAR__MIN CHAR_MIN
-
-/* Strcmp uses unsigned semantics for comparison. */
-int
-simple_strcmp (const char *s1, const char *s2)
-{
- int ret;
-
- while ((ret = *(unsigned char *) s1 - *(unsigned char*) s2++) == 0 && *s1++);
- return ret;
-}
-
-int
-stupid_strcmp (const char *s1, const char *s2)
-{
- size_t ns1 = strlen (s1) + 1;
- size_t ns2 = strlen (s2) + 1;
- size_t n = ns1 < ns2 ? ns1 : ns2;
- int ret = 0;
-
- while (n--)
- if ((ret = *(unsigned char *) s1++ - *(unsigned char *) s2++) != 0)
- break;
- return ret;
-}
-#endif
-
-typedef int (*proto_t) (const CHAR *, const CHAR *);
-
-IMPL (STUPID_STRCMP, 1)
-IMPL (SIMPLE_STRCMP, 1)
-IMPL (STRCMP, 1)
-
-static void
-do_one_test (impl_t *impl,
- const CHAR *s1, const CHAR *s2,
- int exp_result)
-{
- size_t i, iters = INNER_LOOP_ITERS;
- timing_t start, stop, cur;
- TIMING_NOW (start);
- for (i = 0; i < iters; ++i)
- {
- CALL (impl, s1, s2);
- }
- 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, int max_char,
- int exp_result)
-{
- size_t i;
-
- CHAR *s1, *s2;
-
- if (len == 0)
- return;
-
- align1 &= 63;
- if (align1 + (len + 1) * CHARBYTES >= page_size)
- return;
-
- align2 &= 63;
- if (align2 + (len + 1) * CHARBYTES >= page_size)
- return;
-
- /* Put them close to the end of page. */
- i = align1 + CHARBYTES * (len + 2);
- s1 = (CHAR *) (buf1 + ((page_size - i) / 16 * 16) + align1);
- i = align2 + CHARBYTES * (len + 2);
- s2 = (CHAR *) (buf2 + ((page_size - i) / 16 * 16) + align2);
-
- for (i = 0; i < len; i++)
- s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % max_char;
-
- s1[len] = s2[len] = 0;
- s1[len + 1] = 23;
- s2[len + 1] = 24 + exp_result;
- s2[len - 1] -= exp_result;
-
- printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
-
- FOR_EACH_IMPL (impl, 0)
- do_one_test (impl, s1, s2, exp_result);
-
- 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 = 1; i < 32; ++i)
- {
- do_test (CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, 0);
- do_test (CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, 1);
- do_test (CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, -1);
- }
+# define TEST_NAME "strcmp"
- for (i = 1; i < 10 + CHARBYTESLOG; ++i)
- {
- do_test (0, 0, 2 << i, MIDCHAR, 0);
- do_test (0, 0, 2 << i, LARGECHAR, 0);
- do_test (0, 0, 2 << i, MIDCHAR, 1);
- do_test (0, 0, 2 << i, LARGECHAR, 1);
- do_test (0, 0, 2 << i, MIDCHAR, -1);
- do_test (0, 0, 2 << i, LARGECHAR, -1);
- do_test (0, CHARBYTES * i, 2 << i, MIDCHAR, 1);
- do_test (CHARBYTES * i, CHARBYTES * (i + 1), 2 << i, LARGECHAR, 1);
- }
+#define PROTO typedef char *(*proto_t) (char *, const char *);
+#define IMPLS IMPL (strcmp, 1)
- for (i = 1; i < 8; ++i)
- {
- do_test (CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, 0);
- do_test (2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, 0);
- do_test (CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, 1);
- do_test (2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, 1);
- do_test (CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, -1);
- do_test (2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, -1);
- }
- return ret;
-}
+#define CALL2(impl, dst, src, len) CALL (impl, dst, src)
-#include "../test-skeleton.c"
+#include "bench-cmp.h"
diff --git a/benchtests/bench-strncasecmp.c b/benchtests/bench-strncasecmp.c
index 9badd05..dcde4f2 100644
--- a/benchtests/bench-strncasecmp.c
+++ b/benchtests/bench-strncasecmp.c
@@ -16,192 +16,13 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <ctype.h>
-#define TEST_MAIN
-#define TEST_NAME "strncasecmp"
-#include "bench-string.h"
-typedef int (*proto_t) (const char *, const char *, size_t);
-static int simple_strncasecmp (const char *, const char *, size_t);
-static int stupid_strncasecmp (const char *, const char *, size_t);
+# define TEST_NAME "strncasecmp"
-IMPL (stupid_strncasecmp, 0)
-IMPL (simple_strncasecmp, 0)
-IMPL (strncasecmp, 1)
+#define PROTO typedef char *(*proto_t) (char *, const char *, size_t);
+#define IMPLS IMPL (strncasecmp, 1)
-static int
-simple_strncasecmp (const char *s1, const char *s2, size_t n)
-{
- int ret;
- if (n == 0)
- return 0;
+#define CALL2(impl, dst, src, len) CALL (impl, dst, src, len)
- while ((ret = ((unsigned char) tolower (*s1)
- - (unsigned char) tolower (*s2))) == 0
- && *s1++)
- {
- if (--n == 0)
- return 0;
- ++s2;
- }
- return ret;
-}
-
-static int
-stupid_strncasecmp (const char *s1, const char *s2, size_t max)
-{
- size_t ns1 = strlen (s1) + 1;
- size_t ns2 = strlen (s2) + 1;
- size_t n = ns1 < ns2 ? ns1 : ns2;
- if (n > max)
- n = max;
- int ret = 0;
-
- while (n--)
- {
- if ((ret = ((unsigned char) tolower (*s1)
- - (unsigned char) tolower (*s2))) != 0)
- break;
- ++s1;
- ++s2;
- }
- return ret;
-}
-
-static void
-do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n,
- int exp_result)
-{
- size_t i, iters = INNER_LOOP_ITERS;
- timing_t start, stop, cur;
-
- TIMING_NOW (start);
- for (i = 0; i < iters; ++i)
- {
- CALL (impl, s1, s2, n);
- }
- 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 n, size_t len, int max_char,
- int exp_result)
-{
- size_t i;
- char *s1, *s2;
-
- if (len == 0)
- return;
-
- align1 &= 7;
- if (align1 + len + 1 >= page_size)
- return;
-
- align2 &= 7;
- if (align2 + len + 1 >= page_size)
- return;
-
- s1 = (char *) (buf1 + align1);
- s2 = (char *) (buf2 + align2);
-
- for (i = 0; i < len; i++)
- {
- s1[i] = toupper (1 + 23 * i % max_char);
- s2[i] = tolower (s1[i]);
- }
-
- s1[len] = s2[len] = 0;
- s1[len + 1] = 23;
- s2[len + 1] = 24 + exp_result;
- if ((s2[len - 1] == 'z' && exp_result == -1)
- || (s2[len - 1] == 'a' && exp_result == 1))
- s1[len - 1] += exp_result;
- else
- s2[len - 1] -= exp_result;
-
- printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
-
- FOR_EACH_IMPL (impl, 0)
- do_one_test (impl, s1, s2, n, exp_result);
-
- 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 = 1; i < 16; ++i)
- {
- do_test (i, i, i - 1, i, 127, 0);
-
- do_test (i, i, i, i, 127, 0);
- do_test (i, i, i, i, 127, 1);
- do_test (i, i, i, i, 127, -1);
-
- do_test (i, i, i + 1, i, 127, 0);
- do_test (i, i, i + 1, i, 127, 1);
- do_test (i, i, i + 1, i, 127, -1);
- }
-
- for (i = 1; i < 10; ++i)
- {
- do_test (0, 0, (2 << i) - 1, 2 << i, 127, 0);
- do_test (0, 0, 2 << i, 2 << i, 254, 0);
- do_test (0, 0, (2 << i) + 1, 2 << i, 127, 0);
-
- do_test (0, 0, (2 << i) + 1, 2 << i, 254, 0);
-
- do_test (0, 0, 2 << i, 2 << i, 127, 1);
- do_test (0, 0, (2 << i) + 10, 2 << i, 127, 1);
-
- do_test (0, 0, 2 << i, 2 << i, 254, 1);
- do_test (0, 0, (2 << i) + 10, 2 << i, 254, 1);
-
- do_test (0, 0, 2 << i, 2 << i, 127, -1);
- do_test (0, 0, (2 << i) + 10, 2 << i, 127, -1);
-
- do_test (0, 0, 2 << i, 2 << i, 254, -1);
- do_test (0, 0, (2 << i) + 10, 2 << i, 254, -1);
- }
-
- for (i = 1; i < 8; ++i)
- {
- do_test (i, 2 * i, (8 << i) - 1, 8 << i, 127, 0);
- do_test (i, 2 * i, 8 << i, 8 << i, 127, 0);
- do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 0);
-
- do_test (2 * i, i, (8 << i) - 1, 8 << i, 254, 0);
- do_test (2 * i, i, 8 << i, 8 << i, 254, 0);
- do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 0);
-
- do_test (i, 2 * i, 8 << i, 8 << i, 127, 1);
- do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 1);
-
- do_test (2 * i, i, 8 << i, 8 << i, 254, 1);
- do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 1);
-
- do_test (i, 2 * i, 8 << i, 8 << i, 127, -1);
- do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, -1);
-
- do_test (2 * i, i, 8 << i, 8 << i, 254, -1);
- do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, -1);
- }
-
- return ret;
-}
-
-#include "../test-skeleton.c"
+#include "bench-cmp.h"
diff --git a/benchtests/bench-strncmp.c b/benchtests/bench-strncmp.c
index 25df3db..6618021 100644
--- a/benchtests/bench-strncmp.c
+++ b/benchtests/bench-strncmp.c
@@ -16,224 +16,13 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#define TEST_MAIN
-#define TEST_NAME "strncmp"
-#include "bench-string.h"
-typedef int (*proto_t) (const char *, const char *, size_t);
-int simple_strncmp (const char *, const char *, size_t);
-int stupid_strncmp (const char *, const char *, size_t);
+# define TEST_NAME "strncmp"
-IMPL (stupid_strncmp, 0)
-IMPL (simple_strncmp, 0)
-IMPL (strncmp, 1)
+#define PROTO typedef char *(*proto_t) (char *, const char *, size_t);
+#define IMPLS IMPL (strncmp, 1)
-int
-simple_strncmp (const char *s1, const char *s2, size_t n)
-{
- int ret = 0;
- while (n-- && (ret = *(unsigned char *) s1 - * (unsigned char *) s2++) == 0
- && *s1++);
- return ret;
-}
+#define CALL2(impl, dst, src, len) CALL (impl, dst, src, len)
-int
-stupid_strncmp (const char *s1, const char *s2, size_t n)
-{
- size_t ns1 = strnlen (s1, n) + 1, ns2 = strnlen (s2, n) + 1;
- int ret = 0;
-
- n = ns1 < n ? ns1 : n;
- n = ns2 < n ? ns2 : n;
- while (n-- && (ret = *(unsigned char *) s1++ - * (unsigned char *) s2++) == 0);
- return ret;
-}
-
-static void
-do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n,
- int exp_result)
-{
- size_t i, iters = INNER_LOOP_ITERS;
- timing_t start, stop, cur;
-
- TIMING_NOW (start);
- for (i = 0; i < iters; ++i)
- {
- CALL (impl, s1, s2, n);
- }
- TIMING_NOW (stop);
-
- TIMING_DIFF (cur, start, stop);
-
- TIMING_PRINT_MEAN ((double) cur, (double) iters);
-}
-
-static void
-do_test_limit (size_t align1, size_t align2, size_t len, size_t n, int max_char,
- int exp_result)
-{
- size_t i, align_n;
- char *s1, *s2;
-
- if (n == 0)
- {
- s1 = (char*)(buf1 + page_size);
- s2 = (char*)(buf2 + page_size);
- printf ("Length %4zd/%4zd:", len, n);
-
- FOR_EACH_IMPL (impl, 0)
- do_one_test (impl, s1, s2, n, 0);
-
- putchar ('\n');
-
- return;
- }
-
- align1 &= 15;
- align2 &= 15;
- align_n = (page_size - n) & 15;
-
- s1 = (char*)(buf1 + page_size - n);
- s2 = (char*)(buf2 + page_size - n);
-
- if (align1 < align_n)
- s1 -= (align_n - align1);
-
- if (align2 < align_n)
- s2 -= (align_n - align2);
-
- for (i = 0; i < n; i++)
- s1[i] = s2[i] = 1 + 23 * i % max_char;
-
- if (len < n)
- {
- s1[len] = 0;
- s2[len] = 0;
- if (exp_result < 0)
- s2[len] = 32;
- else if (exp_result > 0)
- s1[len] = 64;
- }
-
- printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2);
-
- FOR_EACH_IMPL (impl, 0)
- do_one_test (impl, s1, s2, n, exp_result);
-
- putchar ('\n');
-}
-
-static void
-do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char,
- int exp_result)
-{
- size_t i;
- char *s1, *s2;
-
- if (n == 0)
- return;
-
- align1 &= 7;
- if (align1 + n + 1 >= page_size)
- return;
-
- align2 &= 7;
- if (align2 + n + 1 >= page_size)
- return;
-
- s1 = (char*)(buf1 + align1);
- s2 = (char*)(buf2 + align2);
-
- for (i = 0; i < n; i++)
- s1[i] = s2[i] = 1 + 23 * i % max_char;
-
- s1[n] = 24 + exp_result;
- s2[n] = 23;
- s1[len] = 0;
- s2[len] = 0;
- if (exp_result < 0)
- s2[len] = 32;
- else if (exp_result > 0)
- s1[len] = 64;
- if (len >= n)
- s2[n - 1] -= exp_result;
-
- printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2);
-
- FOR_EACH_IMPL (impl, 0)
- do_one_test (impl, (char*)s1, (char*)s2, n, exp_result);
-
- 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 =0; i < 16; ++i)
- {
- do_test (0, 0, 8, i, 127, 0);
- do_test (0, 0, 8, i, 127, -1);
- do_test (0, 0, 8, i, 127, 1);
- do_test (i, i, 8, i, 127, 0);
- do_test (i, i, 8, i, 127, 1);
- do_test (i, i, 8, i, 127, -1);
- do_test (i, 2 * i, 8, i, 127, 0);
- do_test (2 * i, i, 8, i, 127, 1);
- do_test (i, 3 * i, 8, i, 127, -1);
- do_test (0, 0, 8, i, 255, 0);
- do_test (0, 0, 8, i, 255, -1);
- do_test (0, 0, 8, i, 255, 1);
- do_test (i, i, 8, i, 255, 0);
- do_test (i, i, 8, i, 255, 1);
- do_test (i, i, 8, i, 255, -1);
- do_test (i, 2 * i, 8, i, 255, 0);
- do_test (2 * i, i, 8, i, 255, 1);
- do_test (i, 3 * i, 8, i, 255, -1);
- }
-
- for (i = 1; i < 8; ++i)
- {
- do_test (0, 0, 8 << i, 16 << i, 127, 0);
- do_test (0, 0, 8 << i, 16 << i, 127, 1);
- do_test (0, 0, 8 << i, 16 << i, 127, -1);
- do_test (0, 0, 8 << i, 16 << i, 255, 0);
- do_test (0, 0, 8 << i, 16 << i, 255, 1);
- do_test (0, 0, 8 << i, 16 << i, 255, -1);
- do_test (8 - i, 2 * i, 8 << i, 16 << i, 127, 0);
- do_test (8 - i, 2 * i, 8 << i, 16 << i, 127, 1);
- do_test (2 * i, i, 8 << i, 16 << i, 255, 0);
- do_test (2 * i, i, 8 << i, 16 << i, 255, 1);
- }
-
- do_test_limit (0, 0, 0, 0, 127, 0);
- do_test_limit (4, 0, 21, 20, 127, 0);
- do_test_limit (0, 4, 21, 20, 127, 0);
- do_test_limit (8, 0, 25, 24, 127, 0);
- do_test_limit (0, 8, 25, 24, 127, 0);
-
- for (i = 0; i < 8; ++i)
- {
- do_test_limit (0, 0, 17 - i, 16 - i, 127, 0);
- do_test_limit (0, 0, 17 - i, 16 - i, 255, 0);
- do_test_limit (0, 0, 15 - i, 16 - i, 127, 0);
- do_test_limit (0, 0, 15 - i, 16 - i, 127, 1);
- do_test_limit (0, 0, 15 - i, 16 - i, 127, -1);
- do_test_limit (0, 0, 15 - i, 16 - i, 255, 0);
- do_test_limit (0, 0, 15 - i, 16 - i, 255, 1);
- do_test_limit (0, 0, 15 - i, 16 - i, 255, -1);
- }
-
- return ret;
-}
-
-#include "../test-skeleton.c"
+#include "bench-cmp.h"
--
1.7.10.4