Message ID | 20200612201056.228614-4-hjl.tools@gmail.com |
---|---|
State | New |
Headers | show |
Series | [1/4] strncmp: Add a testcase for page boundary [BZ #25933] | expand |
On 6/12/20 4:10 PM, H.J. Lu via Libc-alpha wrote: > Add strcmp workloads on page boundary. > --- > benchtests/bench-strcmp.c | 48 +++++++++++++++++++++++++++++++++++++++ > 1 file changed, 48 insertions(+) > These additions to the benchmark exercise the page boundary conditions in the algorithms implemented by all the architectures. The test is designed from the experience with bug 25933 in mind so we should mention that in a comment. It could be made a bit more generic by parametrizing vector sizes and number of vector registers that might be grouped e.g. 32 * 4, but it's fine as it is for now to test the page boundary. OK with: - Function rename - Added comments. - s1a iterate over [30,21) Reviewed-by: Carlos O'Donell <carlos@redhat.com> > diff --git a/benchtests/bench-strcmp.c b/benchtests/bench-strcmp.c > index 47d0a35299..3ba1399a4d 100644 > --- a/benchtests/bench-strcmp.c > +++ b/benchtests/bench-strcmp.c > @@ -144,6 +144,52 @@ do_test (json_ctx_t *json_ctx, size_t align1, size_t align2, size_t len, int > json_element_object_end (json_ctx); > } > > +static void > +do_test_page_boundary_1 (json_ctx_t *json_ctx, CHAR *s1, CHAR *s2, Rename to do_one_test_page_boundary () > + size_t align1, size_t align2, size_t len, > + int exp_result) > +{ > + json_element_object_begin (json_ctx); > + json_attr_uint (json_ctx, "length", (double) len); > + json_attr_uint (json_ctx, "align1", (double) align1); > + json_attr_uint (json_ctx, "align2", (double) align2); > + json_array_begin (json_ctx, "timings"); > + FOR_EACH_IMPL (impl, 0) > + do_one_test (json_ctx, impl, s1, s2, exp_result); OK. > + json_array_end (json_ctx); > + json_element_object_end (json_ctx); > +} > + Add a comment: /* To trigger bug 25933 we need a size that is equal to the vector length times 4. In the case of AVX2 for Intel we need 32 * 4. We make this test generic and run it for all architectures as additional boundary testing for such related algorithms. */ > +static void > +do_test_page_boundary (json_ctx_t *json_ctx) > +{ > + size_t size = 32 * 4; > + size_t len; > + CHAR *s1 = (CHAR *) (buf1 + (BUF1PAGES - 1) * page_size); > + CHAR *s2 = (CHAR *) (buf2 + (BUF1PAGES - 1) * page_size); > + int exp_result; > + > + memset (s1, 'a', page_size); > + memset (s2, 'a', page_size); > + > + s1[(page_size / CHARBYTES) - 1] = (CHAR) 0; > + s2[(page_size / CHARBYTES) - 1] = (CHAR) 0; > + Add comment: /* Iterate over a size that is just below where we expect the bug to trigger up to the size we expect will trigger the bug e.g. [99-128]. Likewise iterate the start of two strings between 30 and 31 bytes away from the boundary to simulate alignment changes. */ > + for (size_t s = 99; s <= size; s++) > + for (size_t s1a = 31; s1a < 32; s1a++) Make s1a iterate over [30,32) like s2a. > + for (size_t s2a = 30; s2a < 32; s2a++) > + { > + size_t align1 = (page_size / CHARBYTES - s) - s1a; > + size_t align2 = (page_size / CHARBYTES - s) - s2a; > + CHAR *s1p = s1 + align1; > + CHAR *s2p = s2 + align2; > + len = (page_size / CHARBYTES) - 1 - align1; > + exp_result = SIMPLE_STRCMP (s1p, s2p); > + do_test_page_boundary_1 (json_ctx, s1p, s2p, align1, align2, Call do_one_test_page_boundary () > + len, exp_result); > + } > +} > + > int > test_main (void) > { > @@ -197,6 +243,8 @@ test_main (void) > do_test (&json_ctx, 2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, -1); > } > > + do_test_page_boundary (&json_ctx); OK. > + > json_array_end (&json_ctx); > json_attr_object_end (&json_ctx); > json_attr_object_end (&json_ctx); >
diff --git a/benchtests/bench-strcmp.c b/benchtests/bench-strcmp.c index 47d0a35299..3ba1399a4d 100644 --- a/benchtests/bench-strcmp.c +++ b/benchtests/bench-strcmp.c @@ -144,6 +144,52 @@ do_test (json_ctx_t *json_ctx, size_t align1, size_t align2, size_t len, int json_element_object_end (json_ctx); } +static void +do_test_page_boundary_1 (json_ctx_t *json_ctx, CHAR *s1, CHAR *s2, + size_t align1, size_t align2, size_t len, + int exp_result) +{ + json_element_object_begin (json_ctx); + json_attr_uint (json_ctx, "length", (double) len); + json_attr_uint (json_ctx, "align1", (double) align1); + json_attr_uint (json_ctx, "align2", (double) align2); + json_array_begin (json_ctx, "timings"); + FOR_EACH_IMPL (impl, 0) + do_one_test (json_ctx, impl, s1, s2, exp_result); + json_array_end (json_ctx); + json_element_object_end (json_ctx); +} + +static void +do_test_page_boundary (json_ctx_t *json_ctx) +{ + size_t size = 32 * 4; + size_t len; + CHAR *s1 = (CHAR *) (buf1 + (BUF1PAGES - 1) * page_size); + CHAR *s2 = (CHAR *) (buf2 + (BUF1PAGES - 1) * page_size); + int exp_result; + + memset (s1, 'a', page_size); + memset (s2, 'a', page_size); + + s1[(page_size / CHARBYTES) - 1] = (CHAR) 0; + s2[(page_size / CHARBYTES) - 1] = (CHAR) 0; + + for (size_t s = 99; s <= size; s++) + for (size_t s1a = 31; s1a < 32; s1a++) + for (size_t s2a = 30; s2a < 32; s2a++) + { + size_t align1 = (page_size / CHARBYTES - s) - s1a; + size_t align2 = (page_size / CHARBYTES - s) - s2a; + CHAR *s1p = s1 + align1; + CHAR *s2p = s2 + align2; + len = (page_size / CHARBYTES) - 1 - align1; + exp_result = SIMPLE_STRCMP (s1p, s2p); + do_test_page_boundary_1 (json_ctx, s1p, s2p, align1, align2, + len, exp_result); + } +} + int test_main (void) { @@ -197,6 +243,8 @@ test_main (void) do_test (&json_ctx, 2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, -1); } + do_test_page_boundary (&json_ctx); + json_array_end (&json_ctx); json_attr_object_end (&json_ctx); json_attr_object_end (&json_ctx);