about summary refs log tree commit diff
path: root/benchtests/bench-memchr.c
diff options
context:
space:
mode:
authorStefan Liebler <stli@linux.vnet.ibm.com>2015-08-26 10:26:24 +0200
committerAndreas Krebbel <krebbel@linux.vnet.ibm.com>2015-08-26 10:26:24 +0200
commit88eefd344b3cf4a41284a1dfdaca61667e3a1b4b (patch)
treee6df6d058a7fe251cadaed11918374df46ca7bb9 /benchtests/bench-memchr.c
parentb4c21601b147efc3c2b0e679e4ffc554b3987f0b (diff)
downloadglibc-88eefd344b3cf4a41284a1dfdaca61667e3a1b4b.tar.gz
glibc-88eefd344b3cf4a41284a1dfdaca61667e3a1b4b.tar.xz
glibc-88eefd344b3cf4a41284a1dfdaca61667e3a1b4b.zip
S390: Optimize memchr, rawmemchr and wmemchr.
This patch provides optimized versions of memchr, rawmemchr and wmemchr with the
z13 vector instructions.

ChangeLog:

	* sysdeps/s390/multiarch/memchr-vx.S: New File.
	* sysdeps/s390/multiarch/memchr.c: Likewise.
	* sysdeps/s390/multiarch/rawmemchr-c.c: Likewise.
	* sysdeps/s390/multiarch/rawmemchr-vx.S: Likewise.
	* sysdeps/s390/multiarch/rawmemchr.c: Likewise.
	* sysdeps/s390/multiarch/wmemchr-c.c: Likewise.
	* sysdeps/s390/multiarch/wmemchr-vx.S: Likewise.
	* sysdeps/s390/multiarch/wmemchr.c: Likewise.
	* sysdeps/s390/s390-32/multiarch/memchr.c: Likewise.
	* sysdeps/s390/s390-64/multiarch/memchr.c: Likewise.
	* sysdeps/s390/multiarch/Makefile (sysdep_routines): Add memchr, wmemchr
	and rawmemchr functions.
	* sysdeps/s390/multiarch/ifunc-impl-list-common.c
	(__libc_ifunc_impl_list_common): Add ifunc test for memchr, rawmemchr
	and wmemchr.
	* wcsmbs/wmemchr.c: Use WMEMCHR if defined.
	* string/test-memchr.c: Add wmemchr support.
	* wcsmbs/test-wmemchr.c: New File.
	* wcsmbs/Makefile (strop-tests): Add wmemchr.
	* benchtests/bench-memchr.c: Add wmemchr support.
	* benchtests/bench-wmemchr.c: New File.
	* benchtests/Makefile (wcsmbs-bench): wmemchr.
Diffstat (limited to 'benchtests/bench-memchr.c')
-rw-r--r--benchtests/bench-memchr.c69
1 files changed, 46 insertions, 23 deletions
diff --git a/benchtests/bench-memchr.c b/benchtests/bench-memchr.c
index 9879ec8473..3ead3cd456 100644
--- a/benchtests/bench-memchr.c
+++ b/benchtests/bench-memchr.c
@@ -16,31 +16,52 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#ifndef WIDE
+# define CHAR char
+# define SMALL_CHAR 127
+#else
+# include <wchar.h>
+# define CHAR wchar_t
+# define SMALL_CHAR 1273
+#endif /* WIDE */
+
 #ifndef USE_AS_MEMRCHR
 # define TEST_MAIN
-# define TEST_NAME "memchr"
+# ifndef WIDE
+#  define TEST_NAME "memchr"
+# else
+#  define TEST_NAME "wmemchr"
+# endif /* WIDE */
 # include "bench-string.h"
 
-typedef char *(*proto_t) (const char *, int, size_t);
-char *simple_memchr (const char *, int, size_t);
+# ifndef WIDE
+#  define MEMCHR memchr
+#  define SIMPLE_MEMCHR simple_memchr
+# else
+#  define MEMCHR wmemchr
+#  define SIMPLE_MEMCHR simple_wmemchr
+# endif /* WIDE */
+
+typedef CHAR *(*proto_t) (const CHAR *, int, size_t);
+CHAR *SIMPLE_MEMCHR (const CHAR *, int, size_t);
 
-IMPL (simple_memchr, 0)
-IMPL (memchr, 1)
+IMPL (SIMPLE_MEMCHR, 0)
+IMPL (MEMCHR, 1)
 
-char *
-simple_memchr (const char *s, int c, size_t n)
+CHAR *
+SIMPLE_MEMCHR (const CHAR *s, int c, size_t n)
 {
   while (n--)
-    if (*s++ == (char) c)
-      return (char *) s - 1;
+    if (*s++ == (CHAR) c)
+      return (CHAR *) s - 1;
   return NULL;
 }
-#endif
+#endif /* !USE_AS_MEMRCHR */
 
 static void
-do_one_test (impl_t *impl, const char *s, int c, size_t n, char *exp_res)
+do_one_test (impl_t *impl, const CHAR *s, int c, size_t n, CHAR *exp_res)
 {
-  char *res = CALL (impl, s, c, n);
+  CHAR *res = CALL (impl, s, c, n);
   size_t i, iters = INNER_LOOP_ITERS;
   timing_t start, stop, cur;
 
@@ -68,36 +89,38 @@ static void
 do_test (size_t align, size_t pos, size_t len, int seek_char)
 {
   size_t i;
-  char *result;
+  CHAR *result;
 
   align &= 7;
-  if (align + len >= page_size)
+  if ((align + len) * sizeof (CHAR) >= page_size)
     return;
 
+  CHAR *buf = (CHAR *) (buf1);
+
   for (i = 0; i < len; ++i)
     {
-      buf1[align + i] = 1 + 23 * i % 127;
-      if (buf1[align + i] == seek_char)
-        buf1[align + i] = seek_char + 1;
+      buf[align + i] = 1 + 23 * i % SMALL_CHAR;
+      if (buf[align + i] == seek_char)
+	buf[align + i] = seek_char + 1;
     }
-  buf1[align + len] = 0;
+  buf[align + len] = 0;
 
   if (pos < len)
     {
-      buf1[align + pos] = seek_char;
-      buf1[align + len] = -seek_char;
-      result = (char *) (buf1 + align + pos);
+      buf[align + pos] = seek_char;
+      buf[align + len] = -seek_char;
+      result = (CHAR *) (buf + align + pos);
     }
   else
     {
       result = NULL;
-      buf1[align + len] = seek_char;
+      buf[align + len] = seek_char;
     }
 
   printf ("Length %4zd, alignment %2zd:", pos, align);
 
   FOR_EACH_IMPL (impl, 0)
-    do_one_test (impl, (char *) (buf1 + align), seek_char, len, result);
+    do_one_test (impl, (CHAR *) (buf + align), seek_char, len, result);
 
   putchar ('\n');
 }