]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
benchtests: Add more coverage for strcmp and strncmp benchmarks
authorNoah Goldstein <goldstein.w.n@gmail.com>
Mon, 10 Jan 2022 21:35:40 +0000 (15:35 -0600)
committerNoah Goldstein <goldstein.w.n@gmail.com>
Thu, 3 Feb 2022 22:41:43 +0000 (16:41 -0600)
Add more small and medium sized tests for strcmp and strncmp.

As well for strcmp add option for more direct control of
alignment. Previously alignment was being pushed to the end of the
page. While this is the most difficult case to implement, it is far
from the common case and so shouldn't be the only benchmark.

Signed-off-by: Noah Goldstein <goldstein.w.n@gmail.com>
benchtests/bench-strcmp.c
benchtests/bench-strncmp.c

index 387e76fcfbc9e8ef626982f3d1854d731dc9f9f7..3a60edfb15124e2a7264d0f4bc0692227d06b726 100644 (file)
@@ -99,8 +99,8 @@ do_one_test (json_ctx_t *json_ctx, impl_t *impl,
 }
 
 static void
-do_test (json_ctx_t *json_ctx, size_t align1, size_t align2, size_t len, int
-        max_char, int exp_result)
+do_test (json_ctx_t *json_ctx, size_t align1, size_t align2, size_t len,
+         int max_char, int exp_result, int at_end)
 {
   size_t i;
 
@@ -109,19 +109,28 @@ do_test (json_ctx_t *json_ctx, size_t align1, size_t align2, size_t len, int
   if (len == 0)
     return;
 
-  align1 &= 63;
+  align1 &= ~(CHARBYTES - 1);
+  align2 &= ~(CHARBYTES - 1);
+
+  align1 &= (getpagesize () - 1);
   if (align1 + (len + 1) * CHARBYTES >= page_size)
     return;
 
-  align2 &= 63;
+  align2 &= (getpagesize () - 1);
   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);
+  if (at_end)
+    {
+      i = align1 + CHARBYTES * (len + 2);
+      align1 = ((page_size - i) / 16 * 16) + align1;
+      i = align2 + CHARBYTES * (len + 2);
+      align2 = ((page_size - i) / 16 * 16) + align2;
+    }
+
+  s1 = (CHAR *)(buf1 + align1);
+  s2 = (CHAR *)(buf2 + align2);
 
   for (i = 0; i < len; i++)
     s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % max_char;
@@ -132,9 +141,9 @@ do_test (json_ctx_t *json_ctx, size_t align1, size_t align2, size_t len, int
   s2[len - 1] -= 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_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)
@@ -202,7 +211,8 @@ int
 test_main (void)
 {
   json_ctx_t json_ctx;
-  size_t i;
+  size_t i, j, k;
+  size_t pg_sz = getpagesize ();
 
   test_init ();
 
@@ -221,36 +231,88 @@ test_main (void)
   json_array_end (&json_ctx);
 
   json_array_begin (&json_ctx, "results");
-
-  for (i = 1; i < 32; ++i)
-    {
-      do_test (&json_ctx, CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, 0);
-      do_test (&json_ctx, CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, 1);
-      do_test (&json_ctx, CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, -1);
-    }
-
-  for (i = 1; i < 10 + CHARBYTESLOG; ++i)
+  for (k = 0; k < 2; ++k)
     {
-      do_test (&json_ctx, 0, 0, 2 << i, MIDCHAR, 0);
-      do_test (&json_ctx, 0, 0, 2 << i, LARGECHAR, 0);
-      do_test (&json_ctx, 0, 0, 2 << i, MIDCHAR, 1);
-      do_test (&json_ctx, 0, 0, 2 << i, LARGECHAR, 1);
-      do_test (&json_ctx, 0, 0, 2 << i, MIDCHAR, -1);
-      do_test (&json_ctx, 0, 0, 2 << i, LARGECHAR, -1);
-      do_test (&json_ctx, 0, CHARBYTES * i, 2 << i, MIDCHAR, 1);
-      do_test (&json_ctx, CHARBYTES * i, CHARBYTES * (i + 1), 2 << i, LARGECHAR, 1);
+      for (i = 1; i < 32; ++i)
+        {
+          do_test (&json_ctx, CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, 0, k);
+          do_test (&json_ctx, CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, 1, k);
+          do_test (&json_ctx, CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, -1, k);
+        }
+
+      for (i = 1; i <= 8192;)
+        {
+          /* No page crosses.  */
+          do_test (&json_ctx, 0, 0, i, MIDCHAR, 0, k);
+          do_test (&json_ctx, i * CHARBYTES, 0, i, MIDCHAR, 0, k);
+          do_test (&json_ctx, 0, i * CHARBYTES, i, MIDCHAR, 0, k);
+
+          /* False page crosses.  */
+          do_test (&json_ctx, pg_sz / 2, pg_sz / 2 - CHARBYTES, i, MIDCHAR, 0,
+                   k);
+          do_test (&json_ctx, pg_sz / 2 - CHARBYTES, pg_sz / 2, i, MIDCHAR, 0,
+                   k);
+
+          do_test (&json_ctx, pg_sz - (i * CHARBYTES), 0, i, MIDCHAR, 0, k);
+          do_test (&json_ctx, 0, pg_sz - (i * CHARBYTES), i, MIDCHAR, 0, k);
+
+          /* Real page cross.  */
+          for (j = 16; j < 128; j += 16)
+            {
+              do_test (&json_ctx, pg_sz - j, 0, i, MIDCHAR, 0, k);
+              do_test (&json_ctx, 0, pg_sz - j, i, MIDCHAR, 0, k);
+
+              do_test (&json_ctx, pg_sz - j, pg_sz - j / 2, i, MIDCHAR, 0, k);
+              do_test (&json_ctx, pg_sz - j / 2, pg_sz - j, i, MIDCHAR, 0, k);
+            }
+
+          if (i < 32)
+            {
+              ++i;
+            }
+          else if (i < 160)
+            {
+              i += 8;
+            }
+          else if (i < 512)
+            {
+              i += 32;
+            }
+          else
+            {
+              i *= 2;
+            }
+        }
+
+      for (i = 1; i < 10 + CHARBYTESLOG; ++i)
+        {
+          do_test (&json_ctx, 0, 0, 2 << i, MIDCHAR, 0, k);
+          do_test (&json_ctx, 0, 0, 2 << i, LARGECHAR, 0, k);
+          do_test (&json_ctx, 0, 0, 2 << i, MIDCHAR, 1, k);
+          do_test (&json_ctx, 0, 0, 2 << i, LARGECHAR, 1, k);
+          do_test (&json_ctx, 0, 0, 2 << i, MIDCHAR, -1, k);
+          do_test (&json_ctx, 0, 0, 2 << i, LARGECHAR, -1, k);
+          do_test (&json_ctx, 0, CHARBYTES * i, 2 << i, MIDCHAR, 1, k);
+          do_test (&json_ctx, CHARBYTES * i, CHARBYTES * (i + 1), 2 << i,
+                   LARGECHAR, 1, k);
+        }
+
+      for (i = 1; i < 8; ++i)
+        {
+          do_test (&json_ctx, CHARBYTES * i, 2 * CHARBYTES * i, 8 << i,
+                   MIDCHAR, 0, k);
+          do_test (&json_ctx, 2 * CHARBYTES * i, CHARBYTES * i, 8 << i,
+                   LARGECHAR, 0, k);
+          do_test (&json_ctx, CHARBYTES * i, 2 * CHARBYTES * i, 8 << i,
+                   MIDCHAR, 1, k);
+          do_test (&json_ctx, 2 * CHARBYTES * i, CHARBYTES * i, 8 << i,
+                   LARGECHAR, 1, k);
+          do_test (&json_ctx, CHARBYTES * i, 2 * CHARBYTES * i, 8 << i,
+                   MIDCHAR, -1, k);
+          do_test (&json_ctx, 2 * CHARBYTES * i, CHARBYTES * i, 8 << i,
+                   LARGECHAR, -1, k);
+        }
     }
-
-  for (i = 1; i < 8; ++i)
-    {
-      do_test (&json_ctx, CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, 0);
-      do_test (&json_ctx, 2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, 0);
-      do_test (&json_ctx, CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, 1);
-      do_test (&json_ctx, 2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, 1);
-      do_test (&json_ctx, CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, -1);
-      do_test (&json_ctx, 2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, -1);
-    }
-
   do_test_page_boundary (&json_ctx);
 
   json_array_end (&json_ctx);
index b7a01fde64bf205526a16ba90be0aec74498f23e..6673a535214e27b2a1b21f2680bdc9bb3527202e 100644 (file)
@@ -150,43 +150,43 @@ do_test (json_ctx_t *json_ctx, size_t align1, size_t align2, size_t len, size_t
   if (n == 0)
     return;
 
-  align1 &= 63;
+  align1 &= getpagesize () - 1;
   if (align1 + (n + 1) * CHARBYTES >= page_size)
     return;
 
-  align2 &= 7;
+  align2 &= getpagesize () - 1;
   if (align2 + (n + 1) * CHARBYTES >= page_size)
     return;
 
   json_element_object_begin (json_ctx);
-  json_attr_uint (json_ctx, "strlen", (double) len);
-  json_attr_uint (json_ctx, "len", (double) n);
-  json_attr_uint (json_ctx, "align1", (double) align1);
-  json_attr_uint (json_ctx, "align2", (double) align2);
+  json_attr_uint (json_ctx, "strlen", (double)len);
+  json_attr_uint (json_ctx, "len", (double)n);
+  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)
-    {
-      alloc_bufs ();
-      s1 = (CHAR *) (buf1 + align1);
-      s2 = (CHAR *) (buf2 + align2);
-
-      for (i = 0; i < n; i++)
-       s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * 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;
+  {
+    alloc_bufs ();
+    s1 = (CHAR *)(buf1 + align1);
+    s2 = (CHAR *)(buf2 + align2);
+
+    for (i = 0; i < n; i++)
+      s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * 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;
 
-      do_one_test (json_ctx, impl, s1, s2, n, exp_result);
-    }
+    do_one_test (json_ctx, impl, s1, s2, n, exp_result);
+  }
 
   json_array_end (json_ctx);
   json_element_object_end (json_ctx);
@@ -319,7 +319,8 @@ int
 test_main (void)
 {
   json_ctx_t json_ctx;
-  size_t i;
+  size_t i, j, len;
+  size_t pg_sz = getpagesize ();
 
   test_init ();
 
@@ -334,12 +335,12 @@ test_main (void)
 
   json_array_begin (&json_ctx, "ifuncs");
   FOR_EACH_IMPL (impl, 0)
-    json_element_string (&json_ctx, impl->name);
+  json_element_string (&json_ctx, impl->name);
   json_array_end (&json_ctx);
 
   json_array_begin (&json_ctx, "results");
 
-  for (i =0; i < 16; ++i)
+  for (i = 0; i < 16; ++i)
     {
       do_test (&json_ctx, 0, 0, 8, i, 127, 0);
       do_test (&json_ctx, 0, 0, 8, i, 127, -1);
@@ -361,6 +362,57 @@ test_main (void)
       do_test (&json_ctx, i, 3 * i, 8, i, 255, -1);
     }
 
+  for (len = 0; len <= 128; len += 64)
+    {
+      for (i = 1; i <= 8192;)
+        {
+          /* No page crosses.  */
+          do_test (&json_ctx, 0, 0, i, i + len, 127, 0);
+          do_test (&json_ctx, i * CHARBYTES, 0, i, i + len, 127, 0);
+          do_test (&json_ctx, 0, i * CHARBYTES, i, i + len, 127, 0);
+
+          /* False page crosses.  */
+          do_test (&json_ctx, pg_sz / 2, pg_sz / 2 - CHARBYTES, i, i + len,
+                   127, 0);
+          do_test (&json_ctx, pg_sz / 2 - CHARBYTES, pg_sz / 2, i, i + len,
+                   127, 0);
+
+          do_test (&json_ctx, pg_sz - (i * CHARBYTES), 0, i, i + len, 127,
+                   0);
+          do_test (&json_ctx, 0, pg_sz - (i * CHARBYTES), i, i + len, 127,
+                   0);
+
+          /* Real page cross.  */
+          for (j = 16; j < 128; j += 16)
+            {
+              do_test (&json_ctx, pg_sz - j, 0, i, i + len, 127, 0);
+              do_test (&json_ctx, 0, pg_sz - j, i, i + len, 127, 0);
+
+              do_test (&json_ctx, pg_sz - j, pg_sz - j / 2, i, i + len,
+                       127, 0);
+              do_test (&json_ctx, pg_sz - j / 2, pg_sz - j, i, i + len,
+                       127, 0);
+            }
+
+          if (i < 32)
+            {
+              ++i;
+            }
+          else if (i < 160)
+            {
+              i += 8;
+            }
+          else if (i < 256)
+            {
+              i += 32;
+            }
+          else
+            {
+              i *= 2;
+            }
+        }
+    }
+
   for (i = 1; i < 8; ++i)
     {
       do_test (&json_ctx, 0, 0, 8 << i, 16 << i, 127, 0);