mirror of
git://sourceware.org/git/glibc.git
synced 2025-03-19 13:40:59 +08:00
Copy over string performance tests into benchtests
Copy over already existing string performance tests into benchtests. Bits not related to performance measurements have been omitted.
This commit is contained in:
parent
c1f75dc386
commit
9702047480
62
ChangeLog
62
ChangeLog
@ -1,5 +1,67 @@
|
||||
2013-06-11 Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
|
||||
* benchtests/Makefile (string-bench): Add string benchmarks.
|
||||
* benchtests/bench-bcopy-ifunc.c: New file.
|
||||
* benchtests/bench-bcopy.c: New file.
|
||||
* benchtests/bench-bzero-ifunc.c: New file.
|
||||
* benchtests/bench-bzero.c: New file.
|
||||
* benchtests/bench-memccpy-ifunc.c: New file.
|
||||
* benchtests/bench-memccpy.c: New file.
|
||||
* benchtests/bench-memchr-ifunc.c: New file.
|
||||
* benchtests/bench-memchr.c: New file.
|
||||
* benchtests/bench-memcmp-ifunc.c: New file.
|
||||
* benchtests/bench-memcmp.c: New file.
|
||||
* benchtests/bench-memmem-ifunc.c: New file.
|
||||
* benchtests/bench-memmem.c: New file.
|
||||
* benchtests/bench-memmove-ifunc.c: New file.
|
||||
* benchtests/bench-memmove.c: New file.
|
||||
* benchtests/bench-mempcpy-ifunc.c: New file.
|
||||
* benchtests/bench-mempcpy.c: New file.
|
||||
* benchtests/bench-memset-ifunc.c: New file.
|
||||
* benchtests/bench-memset.c: New file.
|
||||
* benchtests/bench-rawmemchr-ifunc.c: New file.
|
||||
* benchtests/bench-rawmemchr.c: New file.
|
||||
* benchtests/bench-stpcpy-ifunc.c: New file.
|
||||
* benchtests/bench-stpcpy.c: New file.
|
||||
* benchtests/bench-stpncpy-ifunc.c: New file.
|
||||
* benchtests/bench-stpncpy.c: New file.
|
||||
* benchtests/bench-strcasecmp-ifunc.c: New file.
|
||||
* benchtests/bench-strcasecmp.c: New file.
|
||||
* benchtests/bench-strcasestr-ifunc.c: New file.
|
||||
* benchtests/bench-strcasestr.c: New file.
|
||||
* benchtests/bench-strcat-ifunc.c: New file.
|
||||
* benchtests/bench-strcat.c: New file.
|
||||
* benchtests/bench-strchr-ifunc.c: New file.
|
||||
* benchtests/bench-strchr.c: New file.
|
||||
* benchtests/bench-strchrnul-ifunc.c: New file.
|
||||
* benchtests/bench-strchrnul.c: New file.
|
||||
* benchtests/bench-strcmp-ifunc.c: New file.
|
||||
* benchtests/bench-strcmp.c: New file.
|
||||
* benchtests/bench-strcpy-ifunc.c: New file.
|
||||
* benchtests/bench-strcpy.c: New file.
|
||||
* benchtests/bench-strcspn-ifunc.c: New file.
|
||||
* benchtests/bench-strcspn.c: New file.
|
||||
* benchtests/bench-strlen-ifunc.c: New file.
|
||||
* benchtests/bench-strlen.c: New file.
|
||||
* benchtests/bench-strncasecmp-ifunc.c: New file.
|
||||
* benchtests/bench-strncasecmp.c: New file.
|
||||
* benchtests/bench-strncat-ifunc.c: New file.
|
||||
* benchtests/bench-strncat.c: New file.
|
||||
* benchtests/bench-strncmp-ifunc.c: New file.
|
||||
* benchtests/bench-strncmp.c: New file.
|
||||
* benchtests/bench-strncpy-ifunc.c: New file.
|
||||
* benchtests/bench-strncpy.c: New file.
|
||||
* benchtests/bench-strnlen-ifunc.c: New file.
|
||||
* benchtests/bench-strnlen.c: New file.
|
||||
* benchtests/bench-strpbrk-ifunc.c: New file.
|
||||
* benchtests/bench-strpbrk.c: New file.
|
||||
* benchtests/bench-strrchr-ifunc.c: New file.
|
||||
* benchtests/bench-strrchr.c: New file.
|
||||
* benchtests/bench-strspn-ifunc.c: New file.
|
||||
* benchtests/bench-strspn.c: New file.
|
||||
* benchtests/bench-strstr-ifunc.c: New file.
|
||||
* benchtests/bench-strstr.c: New file.
|
||||
|
||||
* benchtests/Makefile: Disable parallel execution of targets.
|
||||
(string-bench): Add memcpy.
|
||||
(benchset): New variable to store a list of benchmark sets.
|
||||
|
@ -24,7 +24,10 @@ bench := acos acosh asin asinh atan atanh cos cosh exp log modf pow rint sin \
|
||||
sinh tan tanh
|
||||
|
||||
# String function benchmarks.
|
||||
string-bench := memcpy
|
||||
string-bench := bcopy bzero memccpy memchr memcmp memmem memmove mempcpy \
|
||||
memset rawmemchr stpcpy stpncpy strcasecmp strcasestr strcat \
|
||||
strchr strchrnul strcmp strcpy strcspn strlen strncasecmp \
|
||||
strncat strncmp strncpy strnlen strpbrk strrchr strspn strstr
|
||||
string-bench-ifunc := $(addsuffix -ifunc, $(string-bench))
|
||||
string-bench-all := $(string-bench) $(string-bench-ifunc)
|
||||
|
||||
|
20
benchtests/bench-bcopy-ifunc.c
Normal file
20
benchtests/bench-bcopy-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of bcopy function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-bcopy.c"
|
20
benchtests/bench-bcopy.c
Normal file
20
benchtests/bench-bcopy.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure bcopy 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 TEST_BCOPY
|
||||
#include "bench-memmove.c"
|
20
benchtests/bench-bzero-ifunc.c
Normal file
20
benchtests/bench-bzero-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of bzero function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-bzero.c"
|
19
benchtests/bench-bzero.c
Normal file
19
benchtests/bench-bzero.c
Normal file
@ -0,0 +1,19 @@
|
||||
/* Measure bzero 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 TEST_BZERO
|
||||
#include "bench-memset.c"
|
20
benchtests/bench-memccpy-ifunc.c
Normal file
20
benchtests/bench-memccpy-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of memccpy function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-memccpy.c"
|
169
benchtests/bench-memccpy.c
Normal file
169
benchtests/bench-memccpy.c
Normal file
@ -0,0 +1,169 @@
|
||||
/* Measure memccpy 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 TEST_MAIN
|
||||
#define TEST_NAME "memccpy"
|
||||
#include "bench-string.h"
|
||||
|
||||
void *simple_memccpy (void *, const void *, int, size_t);
|
||||
void *stupid_memccpy (void *, const void *, int, size_t);
|
||||
|
||||
IMPL (stupid_memccpy, 0)
|
||||
IMPL (simple_memccpy, 0)
|
||||
IMPL (memccpy, 1)
|
||||
|
||||
void *
|
||||
simple_memccpy (void *dst, const void *src, int c, size_t n)
|
||||
{
|
||||
const char *s = src;
|
||||
char *d = dst;
|
||||
|
||||
while (n-- > 0)
|
||||
if ((*d++ = *s++) == (char) c)
|
||||
return d;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
stupid_memccpy (void *dst, const void *src, int c, size_t n)
|
||||
{
|
||||
void *p = memchr (src, c, n);
|
||||
|
||||
if (p != NULL)
|
||||
return mempcpy (dst, src, p - src + 1);
|
||||
|
||||
memcpy (dst, src, n);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedef void *(*proto_t) (void *, const void *, int c, size_t);
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, void *dst, const void *src, int c, size_t len,
|
||||
size_t n)
|
||||
{
|
||||
void *expect = len > n ? NULL : (char *) dst + len;
|
||||
if (CALL (impl, dst, src, c, n) != expect)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
CALL (impl, dst, src, c, n), expect);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (memcmp (dst, src, len > n ? n : len) != 0)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s", impl->name);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute__ ((unused));
|
||||
hp_timing_t stop __attribute__ ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, dst, src, c, n);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, int c, size_t len, size_t n,
|
||||
int max_char)
|
||||
{
|
||||
size_t i;
|
||||
char *s1, *s2;
|
||||
|
||||
align1 &= 7;
|
||||
if (align1 + len >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 7;
|
||||
if (align2 + len >= page_size)
|
||||
return;
|
||||
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0; i < len - 1; ++i)
|
||||
{
|
||||
s1[i] = 32 + 23 * i % (max_char - 32);
|
||||
if (s1[i] == (char) c)
|
||||
--s1[i];
|
||||
}
|
||||
s1[len - 1] = c;
|
||||
for (i = len; i + align1 < page_size && i < len + 64; ++i)
|
||||
s1[i] = 32 + 32 * i % (max_char - 32);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, n %4zd, char %d, alignment %2zd/%2zd:", len, n, c, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s2, s1, c, len, n);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%28s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, i, 12, 16, 16, 127);
|
||||
do_test (i, i, 23, 16, 16, 255);
|
||||
do_test (i, 2 * i, 28, 16, 16, 127);
|
||||
do_test (2 * i, i, 31, 16, 16, 255);
|
||||
do_test (8 - i, 2 * i, 1, 1 << i, 2 << i, 127);
|
||||
do_test (2 * i, 8 - i, 17, 2 << i, 1 << i, 127);
|
||||
do_test (8 - i, 2 * i, 0, 1 << i, 2 << i, 255);
|
||||
do_test (2 * i, 8 - i, i, 2 << i, 1 << i, 255);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, i, 4 << i, 8 << i, 127);
|
||||
do_test (0, 0, i, 16 << i, 8 << i, 127);
|
||||
do_test (8 - i, 2 * i, i, 4 << i, 8 << i, 127);
|
||||
do_test (8 - i, 2 * i, i, 16 << i, 8 << i, 127);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-memchr-ifunc.c
Normal file
20
benchtests/bench-memchr-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of memchr function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-memchr.c"
|
137
benchtests/bench-memchr.c
Normal file
137
benchtests/bench-memchr.c
Normal file
@ -0,0 +1,137 @@
|
||||
/* Measure memchr 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 TEST_MAIN
|
||||
#define TEST_NAME "memchr"
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef char *(*proto_t) (const char *, int, size_t);
|
||||
char *simple_memchr (const char *, int, size_t);
|
||||
|
||||
IMPL (simple_memchr, 0)
|
||||
IMPL (memchr, 1)
|
||||
|
||||
char *
|
||||
simple_memchr (const char *s, int c, size_t n)
|
||||
{
|
||||
while (n--)
|
||||
if (*s++ == (char) c)
|
||||
return (char *) s - 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const char *s, int c, size_t n, char *exp_res)
|
||||
{
|
||||
char *res = CALL (impl, s, c, n);
|
||||
if (res != exp_res)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
res, exp_res);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s, c, n);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, size_t pos, size_t len, int seek_char)
|
||||
{
|
||||
size_t i;
|
||||
char *result;
|
||||
|
||||
align &= 7;
|
||||
if (align + len >= page_size)
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
buf1[align + len] = 0;
|
||||
|
||||
if (pos < len)
|
||||
{
|
||||
buf1[align + pos] = seek_char;
|
||||
buf1[align + len] = -seek_char;
|
||||
result = (char *) (buf1 + align + pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = NULL;
|
||||
buf1[align + len] = seek_char;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd:", pos, align);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, (char *) (buf1 + align), seek_char, len, result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%20s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 16 << i, 2048, 23);
|
||||
do_test (i, 64, 256, 23);
|
||||
do_test (0, 16 << i, 2048, 0);
|
||||
do_test (i, 64, 256, 0);
|
||||
}
|
||||
for (i = 1; i < 32; ++i)
|
||||
{
|
||||
do_test (0, i, i + 1, 23);
|
||||
do_test (0, i, i + 1, 0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-memcmp-ifunc.c
Normal file
20
benchtests/bench-memcmp-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of memcmp function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-memcmp.c"
|
183
benchtests/bench-memcmp.c
Normal file
183
benchtests/bench-memcmp.c
Normal file
@ -0,0 +1,183 @@
|
||||
/* Measure memcmp 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 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)
|
||||
{
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s1, s2, len);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, len, exp_result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
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);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
do_test (0, 0, i, 0);
|
||||
do_test (0, 0, i, 1);
|
||||
do_test (0, 0, i, -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);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-memmem-ifunc.c
Normal file
20
benchtests/bench-memmem-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of memmem function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-memmem.c"
|
172
benchtests/bench-memmem.c
Normal file
172
benchtests/bench-memmem.c
Normal file
@ -0,0 +1,172 @@
|
||||
/* Measure memmem 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 TEST_MAIN
|
||||
#define TEST_NAME "memmem"
|
||||
#define BUF1PAGES 20
|
||||
#define ITERATIONS 500
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef char *(*proto_t) (const void *, size_t, const void *, size_t);
|
||||
void *simple_memmem (const void *, size_t, const void *, size_t);
|
||||
|
||||
IMPL (simple_memmem, 0)
|
||||
IMPL (memmem, 1)
|
||||
|
||||
void *
|
||||
simple_memmem (const void *haystack, size_t haystack_len, const void *needle,
|
||||
size_t needle_len)
|
||||
{
|
||||
const char *begin;
|
||||
const char *const last_possible
|
||||
= (const char *) haystack + haystack_len - needle_len;
|
||||
|
||||
if (needle_len == 0)
|
||||
/* The first occurrence of the empty string is deemed to occur at
|
||||
the beginning of the string. */
|
||||
return (void *) haystack;
|
||||
|
||||
/* Sanity check, otherwise the loop might search through the whole
|
||||
memory. */
|
||||
if (__builtin_expect (haystack_len < needle_len, 0))
|
||||
return NULL;
|
||||
|
||||
for (begin = (const char *) haystack; begin <= last_possible; ++begin)
|
||||
if (begin[0] == ((const char *) needle)[0] &&
|
||||
!memcmp ((const void *) &begin[1],
|
||||
(const void *) ((const char *) needle + 1),
|
||||
needle_len - 1))
|
||||
return (void *) begin;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const void *haystack, size_t haystack_len,
|
||||
const void *needle, size_t needle_len, const void *expected)
|
||||
{
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, haystack, haystack_len, needle, needle_len);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (const char *str, size_t len, size_t idx)
|
||||
{
|
||||
char tmpbuf[len];
|
||||
|
||||
memcpy (tmpbuf, buf1 + idx, len);
|
||||
memcpy (buf1 + idx, str, len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("String %s, offset %zd:", str, idx);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, buf1, BUF1PAGES * page_size, str, len, buf1 + idx);
|
||||
|
||||
memcpy (buf1 + idx, tmpbuf, len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
static void
|
||||
do_random_tests (void)
|
||||
{
|
||||
for (size_t n = 0; n < ITERATIONS; ++n)
|
||||
{
|
||||
char tmpbuf[32];
|
||||
|
||||
size_t shift = random () % 11;
|
||||
size_t rel = random () % ((2 << (shift + 1)) * 64);
|
||||
size_t idx = MIN ((2 << shift) * 64 + rel, BUF1PAGES * page_size - 2);
|
||||
size_t len = random () % (sizeof (tmpbuf) - 1) + 1;
|
||||
len = MIN (len, BUF1PAGES * page_size - idx - 1);
|
||||
memcpy (tmpbuf, buf1 + idx, len);
|
||||
for (size_t i = random () % len / 2 + 1; i > 0; --i)
|
||||
{
|
||||
size_t off = random () % len;
|
||||
char ch = '0' + random () % 10;
|
||||
|
||||
buf1[idx + off] = ch;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("String %.*s, offset %zd:", (int) len, buf1 + idx, idx);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, buf1, BUF1PAGES * page_size, buf1 + idx, len,
|
||||
buf1 + idx);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
|
||||
memcpy (buf1 + idx, tmpbuf, len);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *const strs[] =
|
||||
{
|
||||
"00000", "00112233", "0123456789", "0000111100001111",
|
||||
"00000111110000022222", "012345678901234567890",
|
||||
"abc0", "aaaa0", "abcabc0"
|
||||
};
|
||||
|
||||
|
||||
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 < BUF1PAGES * page_size; ++i)
|
||||
buf1[i] = 60 + random () % 32;
|
||||
|
||||
for (i = 0; i < sizeof (strs) / sizeof (strs[0]); ++i)
|
||||
for (size_t j = 0; j < 120; j += 7)
|
||||
{
|
||||
size_t len = strlen (strs[i]);
|
||||
|
||||
do_test (strs[i], len, j);
|
||||
}
|
||||
|
||||
do_random_tests ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-memmove-ifunc.c
Normal file
20
benchtests/bench-memmove-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of memmove function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-memmove.c"
|
187
benchtests/bench-memmove.c
Normal file
187
benchtests/bench-memmove.c
Normal file
@ -0,0 +1,187 @@
|
||||
/* Measure memmove 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 TEST_MAIN
|
||||
#ifdef TEST_BCOPY
|
||||
# define TEST_NAME "bcopy"
|
||||
#else
|
||||
# define TEST_NAME "memmove"
|
||||
#endif
|
||||
#include "bench-string.h"
|
||||
|
||||
char *simple_memmove (char *, const char *, size_t);
|
||||
|
||||
#ifdef TEST_BCOPY
|
||||
typedef void (*proto_t) (const char *, char *, size_t);
|
||||
void simple_bcopy (const char *, char *, size_t);
|
||||
|
||||
IMPL (simple_bcopy, 0)
|
||||
IMPL (bcopy, 1)
|
||||
|
||||
void
|
||||
simple_bcopy (const char *src, char *dst, size_t n)
|
||||
{
|
||||
simple_memmove (dst, src, n);
|
||||
}
|
||||
#else
|
||||
typedef char *(*proto_t) (char *, const char *, size_t);
|
||||
|
||||
IMPL (simple_memmove, 0)
|
||||
IMPL (memmove, 1)
|
||||
#endif
|
||||
|
||||
char *
|
||||
simple_memmove (char *dst, const char *src, size_t n)
|
||||
{
|
||||
char *ret = dst;
|
||||
if (src < dst)
|
||||
{
|
||||
dst += n;
|
||||
src += n;
|
||||
while (n--)
|
||||
*--dst = *--src;
|
||||
}
|
||||
else
|
||||
while (n--)
|
||||
*dst++ = *src++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, char *dst, char *src, const char *orig_src,
|
||||
size_t len)
|
||||
{
|
||||
memcpy (src, orig_src, len);
|
||||
#ifdef TEST_BCOPY
|
||||
CALL (impl, src, dst, len);
|
||||
#else
|
||||
char *res;
|
||||
|
||||
res = CALL (impl, dst, src, len);
|
||||
if (res != dst)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
res, dst);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (memcmp (dst, orig_src, len) != 0)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"",
|
||||
impl->name, dst, src);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
#ifdef TEST_BCOPY
|
||||
CALL (impl, src, dst, len);
|
||||
#else
|
||||
CALL (impl, dst, src, len);
|
||||
#endif
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s2, (char *) (buf2 + align1), s1, len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
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 < 14; ++i)
|
||||
{
|
||||
do_test (0, 32, 1 << i);
|
||||
do_test (32, 0, 1 << i);
|
||||
do_test (0, i, 1 << i);
|
||||
do_test (i, 0, 1 << i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
do_test (0, 32, i);
|
||||
do_test (32, 0, i);
|
||||
do_test (0, i, i);
|
||||
do_test (i, 0, i);
|
||||
}
|
||||
|
||||
for (i = 3; i < 32; ++i)
|
||||
{
|
||||
if ((i & (i - 1)) == 0)
|
||||
continue;
|
||||
do_test (0, 32, 16 * i);
|
||||
do_test (32, 0, 16 * i);
|
||||
do_test (0, i, 16 * i);
|
||||
do_test (i, 0, 16 * i);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-mempcpy-ifunc.c
Normal file
20
benchtests/bench-mempcpy-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of mempcpy function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-mempcpy.c"
|
37
benchtests/bench-mempcpy.c
Normal file
37
benchtests/bench-mempcpy.c
Normal file
@ -0,0 +1,37 @@
|
||||
/* Measure mempcpy 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) + (len)
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "mempcpy"
|
||||
#include "bench-string.h"
|
||||
|
||||
char *simple_mempcpy (char *, const char *, size_t);
|
||||
|
||||
IMPL (simple_mempcpy, 0)
|
||||
IMPL (mempcpy, 1)
|
||||
|
||||
char *
|
||||
simple_mempcpy (char *dst, const char *src, size_t n)
|
||||
{
|
||||
while (n--)
|
||||
*dst++ = *src++;
|
||||
return dst;
|
||||
}
|
||||
|
||||
#include "bench-memcpy.c"
|
20
benchtests/bench-memset-ifunc.c
Normal file
20
benchtests/bench-memset-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of memset function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-memset.c"
|
169
benchtests/bench-memset.c
Normal file
169
benchtests/bench-memset.c
Normal file
@ -0,0 +1,169 @@
|
||||
/* Measure memset 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 TEST_MAIN
|
||||
#ifdef TEST_BZERO
|
||||
# define TEST_NAME "bzero"
|
||||
#else
|
||||
# define TEST_NAME "memset"
|
||||
#endif
|
||||
#define MIN_PAGE_SIZE 131072
|
||||
#include "bench-string.h"
|
||||
|
||||
char *simple_memset (char *, int, size_t);
|
||||
|
||||
#ifdef TEST_BZERO
|
||||
typedef void (*proto_t) (char *, size_t);
|
||||
void simple_bzero (char *, size_t);
|
||||
void builtin_bzero (char *, size_t);
|
||||
|
||||
IMPL (simple_bzero, 0)
|
||||
IMPL (builtin_bzero, 0)
|
||||
IMPL (bzero, 1)
|
||||
|
||||
void
|
||||
simple_bzero (char *s, size_t n)
|
||||
{
|
||||
simple_memset (s, 0, n);
|
||||
}
|
||||
|
||||
void
|
||||
builtin_bzero (char *s, size_t n)
|
||||
{
|
||||
__builtin_bzero (s, n);
|
||||
}
|
||||
#else
|
||||
typedef char *(*proto_t) (char *, int, size_t);
|
||||
char *builtin_memset (char *, int, size_t);
|
||||
|
||||
IMPL (simple_memset, 0)
|
||||
IMPL (builtin_memset, 0)
|
||||
IMPL (memset, 1)
|
||||
|
||||
char *
|
||||
builtin_memset (char *s, int c, size_t n)
|
||||
{
|
||||
return __builtin_memset (s, c, n);
|
||||
}
|
||||
#endif
|
||||
|
||||
char *
|
||||
simple_memset (char *s, int c, size_t n)
|
||||
{
|
||||
char *r = s, *end = s + n;
|
||||
while (r < end)
|
||||
*r++ = c;
|
||||
return s;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, char *s, int c __attribute ((unused)), size_t n)
|
||||
{
|
||||
char tstbuf[n];
|
||||
#ifdef TEST_BZERO
|
||||
simple_bzero (tstbuf, n);
|
||||
CALL (impl, s, n);
|
||||
if (memcmp (s, tstbuf, n) != 0)
|
||||
#else
|
||||
char *res = CALL (impl, s, c, n);
|
||||
if (res != s
|
||||
|| simple_memset (tstbuf, c, n) != tstbuf
|
||||
|| memcmp (s, tstbuf, n) != 0)
|
||||
#endif
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s", impl->name);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
#ifdef TEST_BZERO
|
||||
CALL (impl, s, n);
|
||||
#else
|
||||
CALL (impl, s, c, n);
|
||||
#endif
|
||||
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, int c, size_t len)
|
||||
{
|
||||
align &= 7;
|
||||
if (align + len > page_size)
|
||||
return;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd, c %2d:", len, align, c);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, (char *) buf1 + align, c, len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
int c = 0;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%24s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
#ifndef TEST_BZERO
|
||||
for (c = -65; c <= 130; c += 65)
|
||||
#endif
|
||||
{
|
||||
for (i = 0; i < 18; ++i)
|
||||
do_test (0, c, 1 << i);
|
||||
for (i = 1; i < 32; ++i)
|
||||
{
|
||||
do_test (i, c, i);
|
||||
if (i & (i - 1))
|
||||
do_test (0, c, i);
|
||||
}
|
||||
do_test (1, c, 14);
|
||||
do_test (3, c, 1024);
|
||||
do_test (4, c, 64);
|
||||
do_test (2, c, 25);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-rawmemchr-ifunc.c
Normal file
20
benchtests/bench-rawmemchr-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of rawmemchr function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-rawmemchr.c"
|
133
benchtests/bench-rawmemchr.c
Normal file
133
benchtests/bench-rawmemchr.c
Normal file
@ -0,0 +1,133 @@
|
||||
/* Measure memchr 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/>. */
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "rawmemchr"
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef char *(*proto_t) (const char *, int);
|
||||
char *simple_rawmemchr (const char *, int);
|
||||
|
||||
IMPL (simple_rawmemchr, 0)
|
||||
IMPL (rawmemchr, 1)
|
||||
|
||||
char *
|
||||
simple_rawmemchr (const char *s, int c)
|
||||
{
|
||||
while (1)
|
||||
if (*s++ == (char) c)
|
||||
return (char *) s - 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const char *s, int c, char *exp_res)
|
||||
{
|
||||
char *res = CALL (impl, s, c);
|
||||
if (res != exp_res)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
res, exp_res);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s, c);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, size_t pos, size_t len, int seek_char)
|
||||
{
|
||||
size_t i;
|
||||
char *result;
|
||||
|
||||
align &= 7;
|
||||
if (align + len >= page_size)
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
buf1[align + len] = 0;
|
||||
|
||||
assert (pos < len);
|
||||
|
||||
buf1[align + pos] = seek_char;
|
||||
buf1[align + len] = -seek_char;
|
||||
result = (char *) (buf1 + align + pos);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd:", pos, align);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, (char *) (buf1 + align), seek_char, result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%20s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 7; ++i)
|
||||
{
|
||||
do_test (0, 16 << i, 2048, 23);
|
||||
do_test (i, 64, 256, 23);
|
||||
do_test (0, 16 << i, 2048, 0);
|
||||
do_test (i, 64, 256, 0);
|
||||
}
|
||||
for (i = 1; i < 32; ++i)
|
||||
{
|
||||
do_test (0, i, i + 1, 23);
|
||||
do_test (0, i, i + 1, 0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-stpcpy-ifunc.c
Normal file
20
benchtests/bench-stpcpy-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of stpcpy function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-stpcpy.c"
|
36
benchtests/bench-stpcpy.c
Normal file
36
benchtests/bench-stpcpy.c
Normal file
@ -0,0 +1,36 @@
|
||||
/* Measure stpcpy 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 STRCPY_RESULT(dst, len) ((dst) + (len))
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "stpcpy"
|
||||
#include "bench-string.h"
|
||||
|
||||
char *simple_stpcpy (char *, const char *);
|
||||
|
||||
IMPL (simple_stpcpy, 0)
|
||||
IMPL (stpcpy, 1)
|
||||
|
||||
char *
|
||||
simple_stpcpy (char *dst, const char *src)
|
||||
{
|
||||
while ((*dst++ = *src++) != '\0');
|
||||
return dst - 1;
|
||||
}
|
||||
|
||||
#include "bench-strcpy.c"
|
20
benchtests/bench-stpncpy-ifunc.c
Normal file
20
benchtests/bench-stpncpy-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of stpncpy function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-stpncpy.c"
|
59
benchtests/bench-stpncpy.c
Normal file
59
benchtests/bench-stpncpy.c
Normal file
@ -0,0 +1,59 @@
|
||||
/* Measure stpncpy 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 STRNCPY_RESULT(dst, len, n) ((dst) + ((len) > (n) ? (n) : (len)))
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "stpncpy"
|
||||
#include "bench-string.h"
|
||||
|
||||
char *simple_stpncpy (char *, const char *, size_t);
|
||||
char *stupid_stpncpy (char *, const char *, size_t);
|
||||
|
||||
IMPL (stupid_stpncpy, 0)
|
||||
IMPL (simple_stpncpy, 0)
|
||||
IMPL (stpncpy, 1)
|
||||
|
||||
char *
|
||||
simple_stpncpy (char *dst, const char *src, size_t n)
|
||||
{
|
||||
while (n--)
|
||||
if ((*dst++ = *src++) == '\0')
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
dst[i] = '\0';
|
||||
return dst - 1;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
char *
|
||||
stupid_stpncpy (char *dst, const char *src, size_t n)
|
||||
{
|
||||
size_t nc = strnlen (src, n);
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < nc; ++i)
|
||||
dst[i] = src[i];
|
||||
for (; i < n; ++i)
|
||||
dst[i] = '\0';
|
||||
return dst + nc;
|
||||
}
|
||||
|
||||
#include "bench-strncpy.c"
|
20
benchtests/bench-strcasecmp-ifunc.c
Normal file
20
benchtests/bench-strcasecmp-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strcasecmp function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strcasecmp.c"
|
183
benchtests/bench-strcasecmp.c
Normal file
183
benchtests/bench-strcasecmp.c
Normal file
@ -0,0 +1,183 @@
|
||||
/* Measure strcasecmp 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/>. */
|
||||
|
||||
#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 *);
|
||||
|
||||
IMPL (stupid_strcasecmp, 0)
|
||||
IMPL (simple_strcasecmp, 0)
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s1, s2);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, exp_result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
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"
|
20
benchtests/bench-strcasestr-ifunc.c
Normal file
20
benchtests/bench-strcasestr-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strcasestr function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strcasestr.c"
|
186
benchtests/bench-strcasestr.c
Normal file
186
benchtests/bench-strcasestr.c
Normal file
@ -0,0 +1,186 @@
|
||||
/* Measure strcasestr 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 TEST_MAIN
|
||||
#define TEST_NAME "strcasestr"
|
||||
#include "bench-string.h"
|
||||
|
||||
|
||||
#define STRCASESTR simple_strcasestr
|
||||
#define NO_ALIAS
|
||||
#define __strncasecmp strncasecmp
|
||||
#include "../string/strcasestr.c"
|
||||
|
||||
|
||||
static char *
|
||||
stupid_strcasestr (const char *s1, const char *s2)
|
||||
{
|
||||
ssize_t s1len = strlen (s1);
|
||||
ssize_t s2len = strlen (s2);
|
||||
|
||||
if (s2len > s1len)
|
||||
return NULL;
|
||||
|
||||
for (ssize_t i = 0; i <= s1len - s2len; ++i)
|
||||
{
|
||||
size_t j;
|
||||
for (j = 0; j < s2len; ++j)
|
||||
if (tolower (s1[i + j]) != tolower (s2[j]))
|
||||
break;
|
||||
if (j == s2len)
|
||||
return (char *) s1 + i;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
typedef char *(*proto_t) (const char *, const char *);
|
||||
|
||||
IMPL (stupid_strcasestr, 0)
|
||||
IMPL (simple_strcasestr, 0)
|
||||
IMPL (strcasestr, 1)
|
||||
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
|
||||
{
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~(hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s1, s2);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len1, size_t len2,
|
||||
int fail)
|
||||
{
|
||||
char *s1 = (char *) (buf1 + align1);
|
||||
char *s2 = (char *) (buf2 + align2);
|
||||
|
||||
static const char d[] = "1234567890abcxyz";
|
||||
#define dl (sizeof (d) - 1)
|
||||
char *ss2 = s2;
|
||||
for (size_t l = len2; l > 0; l = l > dl ? l - dl : 0)
|
||||
{
|
||||
size_t t = l > dl ? dl : l;
|
||||
ss2 = mempcpy (ss2, d, t);
|
||||
}
|
||||
s2[len2] = '\0';
|
||||
|
||||
if (fail)
|
||||
{
|
||||
char *ss1 = s1;
|
||||
for (size_t l = len1; l > 0; l = l > dl ? l - dl : 0)
|
||||
{
|
||||
size_t t = l > dl ? dl : l;
|
||||
memcpy (ss1, d, t);
|
||||
++ss1[len2 > 7 ? 7 : len2 - 1];
|
||||
ss1 += t;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (s1, '0', len1);
|
||||
for (size_t i = 0; i < len2; ++i)
|
||||
s1[len1 - len2 + i] = toupper (s2[i]);
|
||||
}
|
||||
s1[len1] = '\0';
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd/%zd, alignment %2zd/%2zd, %s:",
|
||||
len1, len2, align1, align2, fail ? "fail" : "found");
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, fail ? NULL : s1 + len1 - len2);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
static int
|
||||
test_main (void)
|
||||
{
|
||||
test_init ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (size_t klen = 2; klen < 32; ++klen)
|
||||
for (size_t hlen = 2 * klen; hlen < 16 * klen; hlen += klen)
|
||||
{
|
||||
do_test (0, 0, hlen, klen, 0);
|
||||
do_test (0, 0, hlen, klen, 1);
|
||||
do_test (0, 3, hlen, klen, 0);
|
||||
do_test (0, 3, hlen, klen, 1);
|
||||
do_test (0, 9, hlen, klen, 0);
|
||||
do_test (0, 9, hlen, klen, 1);
|
||||
do_test (0, 15, hlen, klen, 0);
|
||||
do_test (0, 15, hlen, klen, 1);
|
||||
|
||||
do_test (3, 0, hlen, klen, 0);
|
||||
do_test (3, 0, hlen, klen, 1);
|
||||
do_test (3, 3, hlen, klen, 0);
|
||||
do_test (3, 3, hlen, klen, 1);
|
||||
do_test (3, 9, hlen, klen, 0);
|
||||
do_test (3, 9, hlen, klen, 1);
|
||||
do_test (3, 15, hlen, klen, 0);
|
||||
do_test (3, 15, hlen, klen, 1);
|
||||
|
||||
do_test (9, 0, hlen, klen, 0);
|
||||
do_test (9, 0, hlen, klen, 1);
|
||||
do_test (9, 3, hlen, klen, 0);
|
||||
do_test (9, 3, hlen, klen, 1);
|
||||
do_test (9, 9, hlen, klen, 0);
|
||||
do_test (9, 9, hlen, klen, 1);
|
||||
do_test (9, 15, hlen, klen, 0);
|
||||
do_test (9, 15, hlen, klen, 1);
|
||||
|
||||
do_test (15, 0, hlen, klen, 0);
|
||||
do_test (15, 0, hlen, klen, 1);
|
||||
do_test (15, 3, hlen, klen, 0);
|
||||
do_test (15, 3, hlen, klen, 1);
|
||||
do_test (15, 9, hlen, klen, 0);
|
||||
do_test (15, 9, hlen, klen, 1);
|
||||
do_test (15, 15, hlen, klen, 0);
|
||||
do_test (15, 15, hlen, klen, 1);
|
||||
}
|
||||
|
||||
do_test (0, 0, page_size - 1, 16, 0);
|
||||
do_test (0, 0, page_size - 1, 16, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-strcat-ifunc.c
Normal file
20
benchtests/bench-strcat-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strcat function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strcat.c"
|
155
benchtests/bench-strcat.c
Normal file
155
benchtests/bench-strcat.c
Normal file
@ -0,0 +1,155 @@
|
||||
/* Measure strcat 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 TEST_MAIN
|
||||
#define TEST_NAME "strcat"
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef char *(*proto_t) (char *, const char *);
|
||||
char *simple_strcat (char *, const char *);
|
||||
|
||||
IMPL (simple_strcat, 0)
|
||||
IMPL (strcat, 1)
|
||||
|
||||
char *
|
||||
simple_strcat (char *dst, const char *src)
|
||||
{
|
||||
char *ret = dst;
|
||||
while (*dst++ != '\0');
|
||||
--dst;
|
||||
while ((*dst++ = *src++) != '\0');
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, char *dst, const char *src)
|
||||
{
|
||||
size_t k = strlen (dst);
|
||||
if (CALL (impl, dst, src) != dst)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
CALL (impl, dst, src), dst);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp (dst + k, src) != 0)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"",
|
||||
impl->name, dst, src);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
dst[k] = '\0';
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, dst, src);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len1, size_t len2, int max_char)
|
||||
{
|
||||
size_t i;
|
||||
char *s1, *s2;
|
||||
|
||||
align1 &= 7;
|
||||
if (align1 + len1 >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 7;
|
||||
if (align2 + len1 + len2 >= page_size)
|
||||
return;
|
||||
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0; i < len1; ++i)
|
||||
s1[i] = 32 + 23 * i % (max_char - 32);
|
||||
s1[len1] = '\0';
|
||||
|
||||
for (i = 0; i < len2; i++)
|
||||
s2[i] = 32 + 23 * i % (max_char - 32);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len1, len2, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
{
|
||||
s2[len2] = '\0';
|
||||
do_one_test (impl, s2, s1);
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%28s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
do_test (0, 0, i, i, 127);
|
||||
do_test (0, 0, i, i, 255);
|
||||
do_test (0, i, i, i, 127);
|
||||
do_test (i, 0, i, i, 255);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 8 << i, 8 << i, 127);
|
||||
do_test (8 - i, 2 * i, 8 << i, 8 << i, 127);
|
||||
do_test (0, 0, 8 << i, 2 << i, 127);
|
||||
do_test (8 - i, 2 * i, 8 << i, 2 << i, 127);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 2 * i, 8 << i, 1, 127);
|
||||
do_test (2 * i, i, 8 << i, 1, 255);
|
||||
do_test (i, i, 8 << i, 10, 127);
|
||||
do_test (i, i, 8 << i, 10, 255);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-strchr-ifunc.c
Normal file
20
benchtests/bench-strchr-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strchr function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strchr.c"
|
206
benchtests/bench-strchr.c
Normal file
206
benchtests/bench-strchr.c
Normal file
@ -0,0 +1,206 @@
|
||||
/* Measure STRCHR 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 TEST_MAIN
|
||||
#ifndef WIDE
|
||||
# ifdef USE_FOR_STRCHRNUL
|
||||
# define TEST_NAME "strchrnul"
|
||||
# else
|
||||
# define TEST_NAME "strchr"
|
||||
# endif
|
||||
#else
|
||||
# define TEST_NAME "wcschr"
|
||||
#endif
|
||||
#include "bench-string.h"
|
||||
|
||||
#ifndef WIDE
|
||||
# ifdef USE_FOR_STRCHRNUL
|
||||
# define STRCHR strchrnul
|
||||
# define stupid_STRCHR stupid_STRCHRNUL
|
||||
# define simple_STRCHR simple_STRCHRNUL
|
||||
# else
|
||||
# define STRCHR strchr
|
||||
# endif
|
||||
# define STRLEN strlen
|
||||
# define CHAR char
|
||||
# define BIG_CHAR CHAR_MAX
|
||||
# define MIDDLE_CHAR 127
|
||||
# define SMALL_CHAR 23
|
||||
# define UCHAR unsigned char
|
||||
#else
|
||||
# include <wchar.h>
|
||||
# define STRCHR wcschr
|
||||
# define STRLEN wcslen
|
||||
# define CHAR wchar_t
|
||||
# define BIG_CHAR WCHAR_MAX
|
||||
# define MIDDLE_CHAR 1121
|
||||
# define SMALL_CHAR 851
|
||||
# define UCHAR wchar_t
|
||||
#endif
|
||||
|
||||
#ifdef USE_FOR_STRCHRNUL
|
||||
# define NULLRET(endptr) endptr
|
||||
#else
|
||||
# define NULLRET(endptr) NULL
|
||||
#endif
|
||||
|
||||
|
||||
typedef CHAR *(*proto_t) (const CHAR *, int);
|
||||
|
||||
CHAR *
|
||||
simple_STRCHR (const CHAR *s, int c)
|
||||
{
|
||||
for (; *s != (CHAR) c; ++s)
|
||||
if (*s == '\0')
|
||||
return NULLRET ((CHAR *) s);
|
||||
return (CHAR *) s;
|
||||
}
|
||||
|
||||
CHAR *
|
||||
stupid_STRCHR (const CHAR *s, int c)
|
||||
{
|
||||
size_t n = STRLEN (s) + 1;
|
||||
|
||||
while (n--)
|
||||
if (*s++ == (CHAR) c)
|
||||
return (CHAR *) s - 1;
|
||||
return NULLRET ((CHAR *) s - 1);
|
||||
}
|
||||
|
||||
IMPL (stupid_STRCHR, 0)
|
||||
IMPL (simple_STRCHR, 0)
|
||||
IMPL (STRCHR, 1)
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res)
|
||||
{
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s, c);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char)
|
||||
/* For wcschr: align here means align not in bytes,
|
||||
but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
|
||||
len for wcschr here isn't in bytes but it's number of wchar_t symbols. */
|
||||
{
|
||||
size_t i;
|
||||
CHAR *result;
|
||||
CHAR *buf = (CHAR *) buf1;
|
||||
align &= 15;
|
||||
if ((align + len) * sizeof (CHAR) >= page_size)
|
||||
return;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
buf[align + i] = 32 + 23 * i % max_char;
|
||||
if (buf[align + i] == seek_char)
|
||||
buf[align + i] = seek_char + 1;
|
||||
else if (buf[align + i] == 0)
|
||||
buf[align + i] = 1;
|
||||
}
|
||||
buf[align + len] = 0;
|
||||
|
||||
if (pos < len)
|
||||
{
|
||||
buf[align + pos] = seek_char;
|
||||
result = buf + align + pos;
|
||||
}
|
||||
else if (seek_char == 0)
|
||||
result = buf + align + len;
|
||||
else
|
||||
result = NULLRET (buf + align + len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment in bytes %2zd:",
|
||||
pos, align * sizeof (CHAR));
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, buf + align, seek_char, result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%20s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 16 << i, 2048, SMALL_CHAR, MIDDLE_CHAR);
|
||||
do_test (i, 16 << i, 2048, SMALL_CHAR, MIDDLE_CHAR);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 64, 256, SMALL_CHAR, MIDDLE_CHAR);
|
||||
do_test (i, 64, 256, SMALL_CHAR, BIG_CHAR);
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
do_test (0, i, i + 1, SMALL_CHAR, MIDDLE_CHAR);
|
||||
do_test (0, i, i + 1, SMALL_CHAR, BIG_CHAR);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 16 << i, 2048, 0, MIDDLE_CHAR);
|
||||
do_test (i, 16 << i, 2048, 0, MIDDLE_CHAR);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 64, 256, 0, MIDDLE_CHAR);
|
||||
do_test (i, 64, 256, 0, BIG_CHAR);
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
do_test (0, i, i + 1, 0, MIDDLE_CHAR);
|
||||
do_test (0, i, i + 1, 0, BIG_CHAR);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-strchrnul-ifunc.c
Normal file
20
benchtests/bench-strchrnul-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strchrnul function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strchrnul.c"
|
20
benchtests/bench-strchrnul.c
Normal file
20
benchtests/bench-strchrnul.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure strchrnul function.
|
||||
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 USE_FOR_STRCHRNUL 1
|
||||
#include "bench-strchr.c"
|
20
benchtests/bench-strcmp-ifunc.c
Normal file
20
benchtests/bench-strcmp-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strcmp function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strcmp.c"
|
247
benchtests/bench-strcmp.c
Normal file
247
benchtests/bench-strcmp.c
Normal file
@ -0,0 +1,247 @@
|
||||
/* Measure strcmp and wcscmp 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 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)
|
||||
{
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s1, s2);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, exp_result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-strcpy-ifunc.c
Normal file
20
benchtests/bench-strcpy-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strcpy function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strcpy.c"
|
183
benchtests/bench-strcpy.c
Normal file
183
benchtests/bench-strcpy.c
Normal file
@ -0,0 +1,183 @@
|
||||
/* Measure strcpy 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/>. */
|
||||
|
||||
#ifdef WIDE
|
||||
# include <wchar.h>
|
||||
# define CHAR wchar_t
|
||||
# define UCHAR wchar_t
|
||||
# define sfmt "ls"
|
||||
# define BIG_CHAR WCHAR_MAX
|
||||
# define SMALL_CHAR 1273
|
||||
# define STRCMP wcscmp
|
||||
# define MEMCMP wmemcmp
|
||||
# define MEMSET wmemset
|
||||
#else
|
||||
# define CHAR char
|
||||
# define UCHAR unsigned char
|
||||
# define sfmt "s"
|
||||
# define BIG_CHAR CHAR_MAX
|
||||
# define SMALL_CHAR 127
|
||||
# define STRCMP strcmp
|
||||
# define MEMCMP memcmp
|
||||
# define MEMSET memset
|
||||
#endif
|
||||
|
||||
#ifndef STRCPY_RESULT
|
||||
# define STRCPY_RESULT(dst, len) dst
|
||||
# define TEST_MAIN
|
||||
# ifndef WIDE
|
||||
# define TEST_NAME "strcpy"
|
||||
# else
|
||||
# define TEST_NAME "wcscpy"
|
||||
# endif
|
||||
# include "bench-string.h"
|
||||
# ifndef WIDE
|
||||
# define SIMPLE_STRCPY simple_strcpy
|
||||
# define STRCPY strcpy
|
||||
# else
|
||||
# define SIMPLE_STRCPY simple_wcscpy
|
||||
# define STRCPY wcscpy
|
||||
# endif
|
||||
|
||||
CHAR *SIMPLE_STRCPY (CHAR *, const CHAR *);
|
||||
|
||||
IMPL (SIMPLE_STRCPY, 0)
|
||||
IMPL (STRCPY, 1)
|
||||
|
||||
CHAR *
|
||||
SIMPLE_STRCPY (CHAR *dst, const CHAR *src)
|
||||
{
|
||||
CHAR *ret = dst;
|
||||
while ((*dst++ = *src++) != '\0');
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef CHAR *(*proto_t) (CHAR *, const CHAR *);
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, CHAR *dst, const CHAR *src,
|
||||
size_t len __attribute__((unused)))
|
||||
{
|
||||
if (CALL (impl, dst, src) != STRCPY_RESULT (dst, len))
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
CALL (impl, dst, src), STRCPY_RESULT (dst, len));
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (STRCMP (dst, src) != 0)
|
||||
{
|
||||
error (0, 0,
|
||||
"Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
|
||||
impl->name, dst, src);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));;
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, dst, src);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len, int max_char)
|
||||
{
|
||||
size_t i;
|
||||
CHAR *s1, *s2;
|
||||
/* For wcscpy: align1 and align2 here mean alignment not in bytes,
|
||||
but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
|
||||
len for wcschr here isn't in bytes but it's number of wchar_t symbols. */
|
||||
align1 &= 7;
|
||||
if ((align1 + len) * sizeof(CHAR) >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 7;
|
||||
if ((align2 + len) * sizeof(CHAR) >= page_size)
|
||||
return;
|
||||
|
||||
s1 = (CHAR *) (buf1) + align1;
|
||||
s2 = (CHAR *) (buf2) + align2;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
s1[i] = 32 + 23 * i % (max_char - 32);
|
||||
s1[len] = 0;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignments in bytes %2zd/%2zd:", len, align1 * sizeof(CHAR), align2 * sizeof(CHAR));
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s2, s1, len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
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, i, SMALL_CHAR);
|
||||
do_test (0, 0, i, BIG_CHAR);
|
||||
do_test (0, i, i, SMALL_CHAR);
|
||||
do_test (i, 0, i, BIG_CHAR);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 8 << i, SMALL_CHAR);
|
||||
do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 2 * i, 8 << i, SMALL_CHAR);
|
||||
do_test (2 * i, i, 8 << i, BIG_CHAR);
|
||||
do_test (i, i, 8 << i, SMALL_CHAR);
|
||||
do_test (i, i, 8 << i, BIG_CHAR);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-strcspn-ifunc.c
Normal file
20
benchtests/bench-strcspn-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strcspn function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strcspn.c"
|
59
benchtests/bench-strcspn.c
Normal file
59
benchtests/bench-strcspn.c
Normal file
@ -0,0 +1,59 @@
|
||||
/* Measure strcspn 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 STRPBRK_RESULT(s, pos) (pos)
|
||||
#define RES_TYPE size_t
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "strcspn"
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef size_t (*proto_t) (const char *, const char *);
|
||||
size_t simple_strcspn (const char *, const char *);
|
||||
size_t stupid_strcspn (const char *, const char *);
|
||||
|
||||
IMPL (stupid_strcspn, 0)
|
||||
IMPL (simple_strcspn, 0)
|
||||
IMPL (strcspn, 1)
|
||||
|
||||
size_t
|
||||
simple_strcspn (const char *s, const char *rej)
|
||||
{
|
||||
const char *r, *str = s;
|
||||
char c;
|
||||
|
||||
while ((c = *s++) != '\0')
|
||||
for (r = rej; *r != '\0'; ++r)
|
||||
if (*r == c)
|
||||
return s - str - 1;
|
||||
return s - str - 1;
|
||||
}
|
||||
|
||||
size_t
|
||||
stupid_strcspn (const char *s, const char *rej)
|
||||
{
|
||||
size_t ns = strlen (s), nrej = strlen (rej);
|
||||
size_t i, j;
|
||||
|
||||
for (i = 0; i < ns; ++i)
|
||||
for (j = 0; j < nrej; ++j)
|
||||
if (s[i] == rej[j])
|
||||
return i;
|
||||
return i;
|
||||
}
|
||||
|
||||
#include "bench-strpbrk.c"
|
20
benchtests/bench-strlen-ifunc.c
Normal file
20
benchtests/bench-strlen-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strlen function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strlen.c"
|
149
benchtests/bench-strlen.c
Normal file
149
benchtests/bench-strlen.c
Normal file
@ -0,0 +1,149 @@
|
||||
/* Measure STRLEN 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 TEST_MAIN
|
||||
#ifndef WIDE
|
||||
# define TEST_NAME "strlen"
|
||||
#else
|
||||
# define TEST_NAME "wcslen"
|
||||
#endif
|
||||
#include "bench-string.h"
|
||||
|
||||
#ifndef WIDE
|
||||
# define STRLEN strlen
|
||||
# define CHAR char
|
||||
# define MAX_CHAR CHAR_MAX
|
||||
#else
|
||||
# include <wchar.h>
|
||||
# define STRLEN wcslen
|
||||
# define CHAR wchar_t
|
||||
# define MAX_CHAR WCHAR_MAX
|
||||
#endif
|
||||
|
||||
typedef size_t (*proto_t) (const CHAR *);
|
||||
|
||||
size_t
|
||||
simple_STRLEN (const CHAR *s)
|
||||
{
|
||||
const CHAR *p;
|
||||
|
||||
for (p = s; *p; ++p);
|
||||
return p - s;
|
||||
}
|
||||
|
||||
#ifndef WIDE
|
||||
size_t
|
||||
builtin_strlen (const CHAR *p)
|
||||
{
|
||||
return __builtin_strlen (p);
|
||||
}
|
||||
IMPL (builtin_strlen, 0)
|
||||
#endif
|
||||
|
||||
IMPL (simple_STRLEN, 0)
|
||||
IMPL (STRLEN, 1)
|
||||
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const CHAR *s, size_t exp_len)
|
||||
{
|
||||
size_t len = CALL (impl, s);
|
||||
if (len != exp_len)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %zd %zd", impl->name,
|
||||
len, exp_len);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
align &= 63;
|
||||
if (align + sizeof(CHAR) * len >= page_size)
|
||||
return;
|
||||
|
||||
CHAR *buf = (CHAR *) (buf1);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
buf[align + i] = 1 + 11111 * i % MAX_CHAR;
|
||||
buf[align + len] = 0;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd:", len, align);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, (CHAR *) (buf + align), len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%20s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
/* Checking with only 4 * N alignments for wcslen, other alignments are wrong for wchar_t type arrays*/
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (sizeof(CHAR) * i, i);
|
||||
do_test (0, i);
|
||||
}
|
||||
|
||||
for (i = 2; i <= 12; ++i)
|
||||
{
|
||||
do_test (0, 1 << i);
|
||||
do_test (sizeof(CHAR) * 7, 1 << i);
|
||||
do_test (sizeof(CHAR) * i, 1 << i);
|
||||
do_test (sizeof(CHAR) * i, (size_t)((1 << i) / 1.5));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-strncasecmp-ifunc.c
Normal file
20
benchtests/bench-strncasecmp-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strncasecmp function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strncasecmp.c"
|
213
benchtests/bench-strncasecmp.c
Normal file
213
benchtests/bench-strncasecmp.c
Normal file
@ -0,0 +1,213 @@
|
||||
/* Measure strncasecmp 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/>. */
|
||||
|
||||
#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);
|
||||
|
||||
IMPL (stupid_strncasecmp, 0)
|
||||
IMPL (simple_strncasecmp, 0)
|
||||
IMPL (strncasecmp, 1)
|
||||
|
||||
static int
|
||||
simple_strncasecmp (const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
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)
|
||||
{
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s1, s2, n);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, n, exp_result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
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"
|
20
benchtests/bench-strncat-ifunc.c
Normal file
20
benchtests/bench-strncat-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strncat function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strncat.c"
|
168
benchtests/bench-strncat.c
Normal file
168
benchtests/bench-strncat.c
Normal file
@ -0,0 +1,168 @@
|
||||
/* Measure strncat 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 TEST_MAIN
|
||||
#define TEST_NAME "strncat"
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef char *(*proto_t) (char *, const char *, size_t);
|
||||
char *stupid_strncat (char *, const char *, size_t);
|
||||
char *simple_strncat (char *, const char *, size_t);
|
||||
|
||||
IMPL (stupid_strncat, 0)
|
||||
IMPL (strncat, 2)
|
||||
|
||||
char *
|
||||
stupid_strncat (char *dst, const char *src, size_t n)
|
||||
{
|
||||
char *ret = dst;
|
||||
while (*dst++ != '\0');
|
||||
--dst;
|
||||
while (n--)
|
||||
if ( (*dst++ = *src++) == '\0')
|
||||
return ret;
|
||||
*dst = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, char *dst, const char *src, size_t n)
|
||||
{
|
||||
size_t k = strlen (dst);
|
||||
if (CALL (impl, dst, src, n) != dst)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p != %p", impl->name,
|
||||
CALL (impl, dst, src, n), dst);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
size_t len = strlen (src);
|
||||
if (memcmp (dst + k, src, len + 1 > n ? n : len + 1) != 0)
|
||||
{
|
||||
error (0, 0, "Incorrect cancatination in function %s",
|
||||
impl->name);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
if (n < len && dst[k + n] != '\0')
|
||||
{
|
||||
error (0, 0, "There is no zero in the end of output string in %s",
|
||||
impl->name);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
dst[k] = '\0';
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, dst, src, n);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len1, size_t len2,
|
||||
size_t n, int max_char)
|
||||
{
|
||||
size_t i;
|
||||
char *s1, *s2;
|
||||
|
||||
align1 &= 7;
|
||||
if (align1 + len1 >= page_size)
|
||||
return;
|
||||
if (align1 + n > page_size)
|
||||
return;
|
||||
align2 &= 7;
|
||||
if (align2 + len1 + len2 >= page_size)
|
||||
return;
|
||||
if (align2 + len1 + n > page_size)
|
||||
return;
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0; i < len1; ++i)
|
||||
s1[i] = 32 + 23 * i % (max_char - 32);
|
||||
s1[len1] = '\0';
|
||||
|
||||
for (i = 0; i < len2; i++)
|
||||
s2[i] = 32 + 23 * i % (max_char - 32);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd/%4zd, alignment %2zd/%2zd, N %4zd:",
|
||||
len1, len2, align1, align2, n);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
{
|
||||
s2[len2] = '\0';
|
||||
do_one_test (impl, s2, s1, n);
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
size_t i, n;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%28s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (n = 2; n <= 2048; n*=4)
|
||||
{
|
||||
do_test (0, 2, 2, 2, n, 127);
|
||||
do_test (0, 0, 4, 4, n, 127);
|
||||
do_test (4, 0, 4, 4, n, 255);
|
||||
do_test (0, 0, 8, 8, n, 127);
|
||||
do_test (0, 8, 8, 8, n, 127);
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 8 << i, 8 << i, n, 127);
|
||||
do_test (8 - i, 2 * i, 8 << i, 8 << i, n, 127);
|
||||
do_test (0, 0, 8 << i, 2 << i, n, 127);
|
||||
do_test (8 - i, 2 * i, 8 << i, 2 << i, n, 127);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 2 * i, 8 << i, 1, n, 127);
|
||||
do_test (2 * i, i, 8 << i, 1, n, 255);
|
||||
do_test (i, i, 8 << i, 10, n, 127);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
20
benchtests/bench-strncmp-ifunc.c
Normal file
20
benchtests/bench-strncmp-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strncmp function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strncmp.c"
|
249
benchtests/bench-strncmp.c
Normal file
249
benchtests/bench-strncmp.c
Normal file
@ -0,0 +1,249 @@
|
||||
/* Measure 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 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);
|
||||
|
||||
IMPL (stupid_strncmp, 0)
|
||||
IMPL (simple_strncmp, 0)
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s1, s2, n);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd/%4zd:", len, n);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, n, 0);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
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;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
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);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
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;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
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);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
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"
|
20
benchtests/bench-strncpy-ifunc.c
Normal file
20
benchtests/bench-strncpy-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strncpy function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strncpy.c"
|
180
benchtests/bench-strncpy.c
Normal file
180
benchtests/bench-strncpy.c
Normal file
@ -0,0 +1,180 @@
|
||||
/* Measure strncpy 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/>. */
|
||||
|
||||
#ifndef STRNCPY_RESULT
|
||||
# define STRNCPY_RESULT(dst, len, n) dst
|
||||
# define TEST_MAIN
|
||||
# define TEST_NAME "strncpy"
|
||||
# include "bench-string.h"
|
||||
|
||||
char *simple_strncpy (char *, const char *, size_t);
|
||||
char *stupid_strncpy (char *, const char *, size_t);
|
||||
|
||||
IMPL (stupid_strncpy, 0)
|
||||
IMPL (simple_strncpy, 0)
|
||||
IMPL (strncpy, 1)
|
||||
|
||||
char *
|
||||
simple_strncpy (char *dst, const char *src, size_t n)
|
||||
{
|
||||
char *ret = dst;
|
||||
while (n--)
|
||||
if ((*dst++ = *src++) == '\0')
|
||||
{
|
||||
while (n--)
|
||||
*dst++ = '\0';
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
stupid_strncpy (char *dst, const char *src, size_t n)
|
||||
{
|
||||
size_t nc = strnlen (src, n);
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < nc; ++i)
|
||||
dst[i] = src[i];
|
||||
for (; i < n; ++i)
|
||||
dst[i] = '\0';
|
||||
return dst;
|
||||
}
|
||||
#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 n)
|
||||
{
|
||||
if (CALL (impl, dst, src, n) != STRNCPY_RESULT (dst, len, n))
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
CALL (impl, dst, src, n), dst);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (memcmp (dst, src, len > n ? n : len) != 0)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s", impl->name);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (n > len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = len; i < n; ++i)
|
||||
if (dst [i] != '\0')
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s", impl->name);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute__ ((unused));
|
||||
hp_timing_t stop __attribute__ ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, dst, src, n);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char)
|
||||
{
|
||||
size_t i;
|
||||
char *s1, *s2;
|
||||
|
||||
align1 &= 7;
|
||||
if (align1 + len >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 7;
|
||||
if (align2 + len >= page_size)
|
||||
return;
|
||||
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
s1[i] = 32 + 23 * i % (max_char - 32);
|
||||
s1[len] = 0;
|
||||
for (i = len + 1; i + align1 < page_size && i < len + 64; ++i)
|
||||
s1[i] = 32 + 32 * i % (max_char - 32);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, n %4zd, alignment %2zd/%2zd:", len, n, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s2, s1, len, n);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%28s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, i, 16, 16, 127);
|
||||
do_test (i, i, 16, 16, 255);
|
||||
do_test (i, 2 * i, 16, 16, 127);
|
||||
do_test (2 * i, i, 16, 16, 255);
|
||||
do_test (8 - i, 2 * i, 1 << i, 2 << i, 127);
|
||||
do_test (2 * i, 8 - i, 2 << i, 1 << i, 127);
|
||||
do_test (8 - i, 2 * i, 1 << i, 2 << i, 255);
|
||||
do_test (2 * i, 8 - i, 2 << i, 1 << i, 255);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 4 << i, 8 << i, 127);
|
||||
do_test (0, 0, 16 << i, 8 << i, 127);
|
||||
do_test (8 - i, 2 * i, 4 << i, 8 << i, 127);
|
||||
do_test (8 - i, 2 * i, 16 << i, 8 << i, 127);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-strnlen-ifunc.c
Normal file
20
benchtests/bench-strnlen-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strnlen function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strnlen.c"
|
139
benchtests/bench-strnlen.c
Normal file
139
benchtests/bench-strnlen.c
Normal file
@ -0,0 +1,139 @@
|
||||
/* Measure strlen 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 TEST_MAIN
|
||||
#define TEST_NAME "strnlen"
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef size_t (*proto_t) (const char *, size_t);
|
||||
size_t simple_strnlen (const char *, size_t);
|
||||
|
||||
IMPL (simple_strnlen, 0)
|
||||
IMPL (strnlen, 1)
|
||||
|
||||
size_t
|
||||
simple_strnlen (const char *s, size_t maxlen)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < maxlen && s[i]; ++i);
|
||||
return i;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const char *s, size_t maxlen, size_t exp_len)
|
||||
{
|
||||
size_t len = CALL (impl, s, maxlen);
|
||||
if (len != exp_len)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %zd %zd", impl->name,
|
||||
len, exp_len);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s, maxlen);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, size_t len, size_t maxlen, int max_char)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
align &= 7;
|
||||
if (align + len >= page_size)
|
||||
return;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
buf1[align + i] = 1 + 7 * i % max_char;
|
||||
buf1[align + len] = 0;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd:", len, align);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, (char *) (buf1 + align), maxlen, MIN (len, maxlen));
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%20s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, i, i - 1, 127);
|
||||
do_test (0, i, i, 127);
|
||||
do_test (0, i, i + 1, 127);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, i, i - 1, 127);
|
||||
do_test (i, i, i, 127);
|
||||
do_test (i, i, i + 1, 127);
|
||||
}
|
||||
|
||||
for (i = 2; i <= 10; ++i)
|
||||
{
|
||||
do_test (0, 1 << i, 5000, 127);
|
||||
do_test (1, 1 << i, 5000, 127);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
do_test (0, i, 5000, 255);
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
do_test (i, i, 5000, 255);
|
||||
|
||||
for (i = 2; i <= 10; ++i)
|
||||
{
|
||||
do_test (0, 1 << i, 5000, 255);
|
||||
do_test (1, 1 << i, 5000, 255);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-strpbrk-ifunc.c
Normal file
20
benchtests/bench-strpbrk-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strpbrk function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strpbrk.c"
|
182
benchtests/bench-strpbrk.c
Normal file
182
benchtests/bench-strpbrk.c
Normal file
@ -0,0 +1,182 @@
|
||||
/* Measure strpbrk 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/>. */
|
||||
|
||||
#ifndef STRPBRK_RESULT
|
||||
# define STRPBRK_RESULT(s, pos) ((s)[(pos)] ? (s) + (pos) : NULL)
|
||||
# define RES_TYPE char *
|
||||
# define TEST_MAIN
|
||||
# define TEST_NAME "strpbrk"
|
||||
# include "bench-string.h"
|
||||
|
||||
typedef char *(*proto_t) (const char *, const char *);
|
||||
char *simple_strpbrk (const char *, const char *);
|
||||
char *stupid_strpbrk (const char *, const char *);
|
||||
|
||||
IMPL (stupid_strpbrk, 0)
|
||||
IMPL (simple_strpbrk, 0)
|
||||
IMPL (strpbrk, 1)
|
||||
|
||||
char *
|
||||
simple_strpbrk (const char *s, const char *rej)
|
||||
{
|
||||
const char *r;
|
||||
char c;
|
||||
|
||||
while ((c = *s++) != '\0')
|
||||
for (r = rej; *r != '\0'; ++r)
|
||||
if (*r == c)
|
||||
return (char *) s - 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *
|
||||
stupid_strpbrk (const char *s, const char *rej)
|
||||
{
|
||||
size_t ns = strlen (s), nrej = strlen (rej);
|
||||
size_t i, j;
|
||||
|
||||
for (i = 0; i < ns; ++i)
|
||||
for (j = 0; j < nrej; ++j)
|
||||
if (s[i] == rej[j])
|
||||
return (char *) s + i;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const char *s, const char *rej, RES_TYPE exp_res)
|
||||
{
|
||||
RES_TYPE res = CALL (impl, s, rej);
|
||||
if (res != exp_res)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
(void *) res, (void *) exp_res);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s, rej);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, size_t pos, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
int c;
|
||||
RES_TYPE result;
|
||||
char *rej, *s;
|
||||
|
||||
align &= 7;
|
||||
if (align + pos + 10 >= page_size || len > 240)
|
||||
return;
|
||||
|
||||
rej = (char *) (buf2 + (random () & 255));
|
||||
s = (char *) (buf1 + align);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
rej[i] = random () & 255;
|
||||
if (!rej[i])
|
||||
rej[i] = random () & 255;
|
||||
if (!rej[i])
|
||||
rej[i] = 1 + (random () & 127);
|
||||
}
|
||||
rej[len] = '\0';
|
||||
for (c = 1; c <= 255; ++c)
|
||||
if (strchr (rej, c) == NULL)
|
||||
break;
|
||||
|
||||
for (i = 0; i < pos; ++i)
|
||||
{
|
||||
s[i] = random () & 255;
|
||||
if (strchr (rej, s[i]))
|
||||
{
|
||||
s[i] = random () & 255;
|
||||
if (strchr (rej, s[i]))
|
||||
s[i] = c;
|
||||
}
|
||||
}
|
||||
s[pos] = rej[random () % (len + 1)];
|
||||
if (s[pos])
|
||||
{
|
||||
for (i = pos + 1; i < pos + 10; ++i)
|
||||
s[i] = random () & 255;
|
||||
s[i] = '\0';
|
||||
}
|
||||
result = STRPBRK_RESULT (s, pos);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd, rej len %2zd:", pos, align, len);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s, rej, result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%32s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
do_test (0, 512, i);
|
||||
do_test (i, 512, i);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 16 << i, 4);
|
||||
do_test (i, 16 << i, 4);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
do_test (i, 64, 10);
|
||||
|
||||
for (i = 0; i < 64; ++i)
|
||||
do_test (0, i, 6);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-strrchr-ifunc.c
Normal file
20
benchtests/bench-strrchr-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strrchr function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strrchr.c"
|
190
benchtests/bench-strrchr.c
Normal file
190
benchtests/bench-strrchr.c
Normal file
@ -0,0 +1,190 @@
|
||||
/* Measure STRCHR 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 TEST_MAIN
|
||||
#ifdef WIDE
|
||||
# define TEST_NAME "wcsrchr"
|
||||
#else
|
||||
# define TEST_NAME "strrchr"
|
||||
#endif
|
||||
#include "bench-string.h"
|
||||
|
||||
#ifdef WIDE
|
||||
# include <wchar.h>
|
||||
# define SIMPLE_STRRCHR simple_wcsrchr
|
||||
# define STRRCHR wcsrchr
|
||||
# define CHAR wchar_t
|
||||
# define UCHAR wchar_t
|
||||
# define BIG_CHAR WCHAR_MAX
|
||||
# define SMALL_CHAR 1273
|
||||
#else
|
||||
# define SIMPLE_STRRCHR simple_strrchr
|
||||
# define STRRCHR strrchr
|
||||
# define CHAR char
|
||||
# define UCHAR unsigned char
|
||||
# define BIG_CHAR CHAR_MAX
|
||||
# define SMALL_CHAR 127
|
||||
#endif
|
||||
|
||||
typedef CHAR *(*proto_t) (const CHAR *, int);
|
||||
CHAR *SIMPLE_STRRCHR (const CHAR *, int);
|
||||
|
||||
IMPL (SIMPLE_STRRCHR, 0)
|
||||
IMPL (STRRCHR, 1)
|
||||
|
||||
CHAR *
|
||||
SIMPLE_STRRCHR (const CHAR *s, int c)
|
||||
{
|
||||
const CHAR *ret = NULL;
|
||||
|
||||
for (; *s != '\0'; ++s)
|
||||
if (*s == (CHAR) c)
|
||||
ret = s;
|
||||
|
||||
return (CHAR *) (c == '\0' ? s : ret);
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const CHAR *s, int c, CHAR *exp_res)
|
||||
{
|
||||
CHAR *res = CALL (impl, s, c);
|
||||
if (res != exp_res)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
res, exp_res);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s, c);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char)
|
||||
/* For wcsrchr: align here means align not in bytes,
|
||||
but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
|
||||
len for wcschr here isn't in bytes but it's number of wchar_t symbols. */
|
||||
{
|
||||
size_t i;
|
||||
CHAR *result;
|
||||
CHAR *buf = (CHAR *) buf1;
|
||||
|
||||
align &= 7;
|
||||
if ( (align + len) * sizeof(CHAR) >= page_size)
|
||||
return;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
buf[align + i] = (random () * random ()) & max_char;
|
||||
if (!buf[align + i])
|
||||
buf[align + i] = (random () * random ()) & max_char;
|
||||
if (!buf[align + i])
|
||||
buf[align + i] = 1;
|
||||
if ((i > pos || pos >= len) && buf[align + i] == seek_char)
|
||||
buf[align + i] = seek_char + 10 + (random () & 15);
|
||||
}
|
||||
buf[align + len] = 0;
|
||||
|
||||
if (pos < len)
|
||||
{
|
||||
buf[align + pos] = seek_char;
|
||||
result = (CHAR *) (buf + align + pos);
|
||||
}
|
||||
else if (seek_char == 0)
|
||||
result = (CHAR *) (buf + align + len);
|
||||
else
|
||||
result = NULL;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment in bytes %2zd:", pos, align * sizeof(CHAR));
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, (CHAR *) (buf + align), seek_char, result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%20s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 16 << i, 2048, 23, SMALL_CHAR);
|
||||
do_test (i, 16 << i, 2048, 23, SMALL_CHAR);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 64, 256, 23, SMALL_CHAR);
|
||||
do_test (i, 64, 256, 23, BIG_CHAR);
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
do_test (0, i, i + 1, 23, SMALL_CHAR);
|
||||
do_test (0, i, i + 1, 23, BIG_CHAR);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 16 << i, 2048, 0, SMALL_CHAR);
|
||||
do_test (i, 16 << i, 2048, 0, SMALL_CHAR);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 64, 256, 0, SMALL_CHAR);
|
||||
do_test (i, 64, 256, 0, BIG_CHAR);
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
do_test (0, i, i + 1, 0, SMALL_CHAR);
|
||||
do_test (0, i, i + 1, 0, BIG_CHAR);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-strspn-ifunc.c
Normal file
20
benchtests/bench-strspn-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strspn function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strspn.c"
|
174
benchtests/bench-strspn.c
Normal file
174
benchtests/bench-strspn.c
Normal file
@ -0,0 +1,174 @@
|
||||
/* Measure strspn 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 TEST_MAIN
|
||||
#define TEST_NAME "strspn"
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef size_t (*proto_t) (const char *, const char *);
|
||||
size_t simple_strspn (const char *, const char *);
|
||||
size_t stupid_strspn (const char *, const char *);
|
||||
|
||||
IMPL (stupid_strspn, 0)
|
||||
IMPL (simple_strspn, 0)
|
||||
IMPL (strspn, 1)
|
||||
|
||||
size_t
|
||||
simple_strspn (const char *s, const char *acc)
|
||||
{
|
||||
const char *r, *str = s;
|
||||
char c;
|
||||
|
||||
while ((c = *s++) != '\0')
|
||||
{
|
||||
for (r = acc; *r != '\0'; ++r)
|
||||
if (*r == c)
|
||||
break;
|
||||
if (*r == '\0')
|
||||
return s - str - 1;
|
||||
}
|
||||
return s - str - 1;
|
||||
}
|
||||
|
||||
size_t
|
||||
stupid_strspn (const char *s, const char *acc)
|
||||
{
|
||||
size_t ns = strlen (s), nacc = strlen (acc);
|
||||
size_t i, j;
|
||||
|
||||
for (i = 0; i < ns; ++i)
|
||||
{
|
||||
for (j = 0; j < nacc; ++j)
|
||||
if (s[i] == acc[j])
|
||||
break;
|
||||
if (j == nacc)
|
||||
return i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const char *s, const char *acc, size_t exp_res)
|
||||
{
|
||||
size_t res = CALL (impl, s, acc);
|
||||
if (res != exp_res)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
(void *) res, (void *) exp_res);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s, acc);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, size_t pos, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
char *acc, *s;
|
||||
|
||||
align &= 7;
|
||||
if (align + pos + 10 >= page_size || len > 240 || ! len)
|
||||
return;
|
||||
|
||||
acc = (char *) (buf2 + (random () & 255));
|
||||
s = (char *) (buf1 + align);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
acc[i] = random () & 255;
|
||||
if (!acc[i])
|
||||
acc[i] = random () & 255;
|
||||
if (!acc[i])
|
||||
acc[i] = 1 + (random () & 127);
|
||||
}
|
||||
acc[len] = '\0';
|
||||
|
||||
for (i = 0; i < pos; ++i)
|
||||
s[i] = acc[random () % len];
|
||||
s[pos] = random () & 255;
|
||||
if (strchr (acc, s[pos]))
|
||||
s[pos] = '\0';
|
||||
else
|
||||
{
|
||||
for (i = pos + 1; i < pos + 10; ++i)
|
||||
s[i] = random () & 255;
|
||||
s[i] = '\0';
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd, acc len %2zd:", pos, align, len);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s, acc, pos);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%32s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
do_test (0, 512, i);
|
||||
do_test (i, 512, i);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 16 << i, 4);
|
||||
do_test (i, 16 << i, 4);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
do_test (i, 64, 10);
|
||||
|
||||
for (i = 0; i < 64; ++i)
|
||||
do_test (0, i, 6);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
20
benchtests/bench-strstr-ifunc.c
Normal file
20
benchtests/bench-strstr-ifunc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strstr function.
|
||||
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 TEST_IFUNC 1
|
||||
#include "bench-strstr.c"
|
183
benchtests/bench-strstr.c
Normal file
183
benchtests/bench-strstr.c
Normal file
@ -0,0 +1,183 @@
|
||||
/* Measure strstr 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 TEST_MAIN
|
||||
#define TEST_NAME "strstr"
|
||||
#include "bench-string.h"
|
||||
|
||||
|
||||
#define STRSTR simple_strstr
|
||||
#include "../string/strstr.c"
|
||||
|
||||
|
||||
static char *
|
||||
stupid_strstr (const char *s1, const char *s2)
|
||||
{
|
||||
ssize_t s1len = strlen (s1);
|
||||
ssize_t s2len = strlen (s2);
|
||||
|
||||
if (s2len > s1len)
|
||||
return NULL;
|
||||
|
||||
for (ssize_t i = 0; i <= s1len - s2len; ++i)
|
||||
{
|
||||
size_t j;
|
||||
for (j = 0; j < s2len; ++j)
|
||||
if (s1[i + j] != s2[j])
|
||||
break;
|
||||
if (j == s2len)
|
||||
return (char *) s1 + i;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
typedef char *(*proto_t) (const char *, const char *);
|
||||
|
||||
IMPL (stupid_strstr, 0)
|
||||
IMPL (simple_strstr, 0)
|
||||
IMPL (strstr, 1)
|
||||
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
|
||||
{
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~(hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s1, s2);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len1, size_t len2,
|
||||
int fail)
|
||||
{
|
||||
char *s1 = (char *) (buf1 + align1);
|
||||
char *s2 = (char *) (buf2 + align2);
|
||||
|
||||
static const char d[] = "1234567890abcdef";
|
||||
#define dl (sizeof (d) - 1)
|
||||
char *ss2 = s2;
|
||||
for (size_t l = len2; l > 0; l = l > dl ? l - dl : 0)
|
||||
{
|
||||
size_t t = l > dl ? dl : l;
|
||||
ss2 = mempcpy (ss2, d, t);
|
||||
}
|
||||
s2[len2] = '\0';
|
||||
|
||||
if (fail)
|
||||
{
|
||||
char *ss1 = s1;
|
||||
for (size_t l = len1; l > 0; l = l > dl ? l - dl : 0)
|
||||
{
|
||||
size_t t = l > dl ? dl : l;
|
||||
memcpy (ss1, d, t);
|
||||
++ss1[len2 > 7 ? 7 : len2 - 1];
|
||||
ss1 += t;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (s1, '0', len1);
|
||||
memcpy (s1 + len1 - len2, s2, len2);
|
||||
}
|
||||
s1[len1] = '\0';
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd/%zd, alignment %2zd/%2zd, %s:",
|
||||
len1, len2, align1, align2, fail ? "fail" : "found");
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, fail ? NULL : s1 + len1 - len2);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
static int
|
||||
test_main (void)
|
||||
{
|
||||
test_init ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (size_t klen = 2; klen < 32; ++klen)
|
||||
for (size_t hlen = 2 * klen; hlen < 16 * klen; hlen += klen)
|
||||
{
|
||||
do_test (0, 0, hlen, klen, 0);
|
||||
do_test (0, 0, hlen, klen, 1);
|
||||
do_test (0, 3, hlen, klen, 0);
|
||||
do_test (0, 3, hlen, klen, 1);
|
||||
do_test (0, 9, hlen, klen, 0);
|
||||
do_test (0, 9, hlen, klen, 1);
|
||||
do_test (0, 15, hlen, klen, 0);
|
||||
do_test (0, 15, hlen, klen, 1);
|
||||
|
||||
do_test (3, 0, hlen, klen, 0);
|
||||
do_test (3, 0, hlen, klen, 1);
|
||||
do_test (3, 3, hlen, klen, 0);
|
||||
do_test (3, 3, hlen, klen, 1);
|
||||
do_test (3, 9, hlen, klen, 0);
|
||||
do_test (3, 9, hlen, klen, 1);
|
||||
do_test (3, 15, hlen, klen, 0);
|
||||
do_test (3, 15, hlen, klen, 1);
|
||||
|
||||
do_test (9, 0, hlen, klen, 0);
|
||||
do_test (9, 0, hlen, klen, 1);
|
||||
do_test (9, 3, hlen, klen, 0);
|
||||
do_test (9, 3, hlen, klen, 1);
|
||||
do_test (9, 9, hlen, klen, 0);
|
||||
do_test (9, 9, hlen, klen, 1);
|
||||
do_test (9, 15, hlen, klen, 0);
|
||||
do_test (9, 15, hlen, klen, 1);
|
||||
|
||||
do_test (15, 0, hlen, klen, 0);
|
||||
do_test (15, 0, hlen, klen, 1);
|
||||
do_test (15, 3, hlen, klen, 0);
|
||||
do_test (15, 3, hlen, klen, 1);
|
||||
do_test (15, 9, hlen, klen, 0);
|
||||
do_test (15, 9, hlen, klen, 1);
|
||||
do_test (15, 15, hlen, klen, 0);
|
||||
do_test (15, 15, hlen, klen, 1);
|
||||
}
|
||||
|
||||
do_test (0, 0, page_size - 1, 16, 0);
|
||||
do_test (0, 0, page_size - 1, 16, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
Loading…
x
Reference in New Issue
Block a user