Re: [PATCH 1/2] string: Speed up strcmp test data initialization
Adhemerval Zanella Netto <[email protected]> Fri, 7 Aug 2026 10:35:48 -0300
| Newsgroups | gmane.comp.lib.glibc.alpha |
|---|---|
| Organization | Linaro |
| Message-ID | <[email protected]> |
On 05/08/26 18:14, Magnus Lindholm wrote: > The strcmp and strncmp tests repeatedly initialize large buffers for > many combinations of lengths and alignments. The existing loops > perform a remainder operation and two individual stores for every > element. > > Generate at most max_char elements using an additive recurrence. The > recurrence produces the same sequence as the existing multiplication > and remainder expression. Expand this initial pattern using bulk > copies, and then copy the completed first buffer to the second buffer. > > This preserves the generated test data while substantially reducing > the initialization cost on slower systems. > > The change also applies to the wcscmp and wcsncmp tests, which include > the same test sources. > > Signed-off-by: Magnus Lindholm <[email protected]> Nice catch, LTGM. Reviewed-by: Adhemerval Zanella <[email protected]> > --- > string/test-strcmp.c | 28 ++++++++++++++++++++++++++-- > string/test-strncmp.c | 28 ++++++++++++++++++++++++++-- > 2 files changed, 52 insertions(+), 4 deletions(-) > > diff --git a/string/test-strcmp.c b/string/test-strcmp.c > index 76ccff46e2..ca52827b11 100644 > --- a/string/test-strcmp.c > +++ b/string/test-strcmp.c > @@ -156,6 +156,10 @@ do_test (size_t align1, size_t align2, size_t len, int max_char, > int exp_result) > { > size_t i; > + size_t value = 0; > + size_t pattern_len; > + size_t step > + = (23U << ((CHARBYTES - 1) * 8)) % (size_t) max_char; > > CHAR *s1, *s2; > > @@ -179,8 +183,28 @@ do_test (size_t align1, size_t align2, size_t len, int max_char, > 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; > + /* The generated sequence repeats after at most max_char elements. */ > + pattern_len > + = len < (size_t) max_char ? len : (size_t) max_char; > + > + for (i = 0; i < pattern_len; i++) > + { > + s1[i] = 1 + value; > + > + value += step; > + if (value >= (size_t) max_char) > + value -= max_char; > + } > + > + while (i < len) > + { > + size_t copy = i < len - i ? i : len - i; > + > + MEMCPY (s1 + i, s1, copy); > + i += copy; > + } > + > + MEMCPY (s2, s1, len); > > s1[len] = s2[len] = 0; > s1[len + 1] = 23; > diff --git a/string/test-strncmp.c b/string/test-strncmp.c > index 54ada39eb2..9da0f21f60 100644 > --- a/string/test-strncmp.c > +++ b/string/test-strncmp.c > @@ -190,6 +190,9 @@ do_test_n (size_t align1, size_t align2, size_t len, size_t n, int n_in_bounds, > { > size_t i, buf_bound; > CHAR *s1, *s2, *s1_end, *s2_end; > + size_t value = 0; > + size_t pattern_len; > + size_t step = (23U << ((CHARBYTES - 1) * 8)) % (size_t) max_char; > > align1 &= ~(CHARBYTES - 1); > align2 &= ~(CHARBYTES - 1); > @@ -216,8 +219,29 @@ do_test_n (size_t align1, size_t align2, size_t len, size_t n, int n_in_bounds, > s2[n] = 23; > } > > - for (i = 0; i < buf_bound; i++) > - s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % max_char; > + /* The generated sequence repeats after at most max_char elements. */ > + pattern_len > + = buf_bound < (size_t) max_char > + ? buf_bound : (size_t) max_char; > + > + for (i = 0; i < pattern_len; i++) > + { > + s1[i] = 1 + value; > + > + value += step; > + if (value >= (size_t) max_char) > + value -= max_char; > + } > + > + while (i < buf_bound) > + { > + size_t copy = i < buf_bound - i ? i : buf_bound - i; > + > + MEMCPY (s1 + i, s1, copy); > + i += copy; > + } > + > + MEMCPY (s2, s1, buf_bound); > > s1[len] = 0; > s2[len] = 0;