From 88eefd344b3cf4a41284a1dfdaca61667e3a1b4b Mon Sep 17 00:00:00 2001 From: Stefan Liebler Date: Wed, 26 Aug 2015 10:26:24 +0200 Subject: 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. --- benchtests/Makefile | 3 +- benchtests/bench-memchr.c | 69 ++++++++++++++++++++++++++++++---------------- benchtests/bench-wmemchr.c | 20 ++++++++++++++ 3 files changed, 68 insertions(+), 24 deletions(-) create mode 100644 benchtests/bench-wmemchr.c (limited to 'benchtests') diff --git a/benchtests/Makefile b/benchtests/Makefile index 46cb34f5b5..95712a32ae 100644 --- a/benchtests/Makefile +++ b/benchtests/Makefile @@ -37,7 +37,8 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok \ strcoll wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat \ - wcscmp wcsncmp wcschr wcschrnul wcsrchr wcsspn wcspbrk wcscspn + wcscmp wcsncmp wcschr wcschrnul wcsrchr wcsspn wcspbrk wcscspn \ + wmemchr string-bench-all := $(string-bench) ${wcsmbs-bench} # We have to generate locales 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 . */ +#ifndef WIDE +# define CHAR char +# define SMALL_CHAR 127 +#else +# include +# 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'); } diff --git a/benchtests/bench-wmemchr.c b/benchtests/bench-wmemchr.c new file mode 100644 index 0000000000..d796a69726 --- /dev/null +++ b/benchtests/bench-wmemchr.c @@ -0,0 +1,20 @@ +/* Measure wmemchr functions. + Copyright (C) 2015 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 + . */ + +#define WIDE 1 +#include "bench-memchr.c" -- cgit 1.4.1