summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
authorNoah Goldstein <goldstein.w.n@gmail.com>2022-05-19 17:18:03 -0500
committerNoah Goldstein <goldstein.w.n@gmail.com>2022-05-23 10:38:40 -0500
commit9a421348cd7d0704663e26e6171828bed6e0a2cf (patch)
tree8bdbf5e9d77420298f1795467dda50ed4e39afb0 /elf
parent3d155d4b6c29ddfd0b3318fa58dbf8ef20e7bca0 (diff)
downloadglibc-9a421348cd7d0704663e26e6171828bed6e0a2cf.tar.gz
glibc-9a421348cd7d0704663e26e6171828bed6e0a2cf.tar.xz
glibc-9a421348cd7d0704663e26e6171828bed6e0a2cf.zip
elf: Optimize _dl_new_hash in dl-new-hash.h
Unroll slightly and enforce good instruction scheduling. This improves
performance on out-of-order machines. The unrolling allows for
pipelined multiplies.

As well, as an optional sysdep, reorder the operations and prevent
reassosiation for better scheduling and higher ILP. This commit
only adds the barrier for x86, although it should be either no
change or a win for any architecture.

Unrolling further started to induce slowdowns for sizes [0, 4]
but can help the loop so if larger sizes are the target further
unrolling can be beneficial.

Results for _dl_new_hash
Benchmarked on Tigerlake: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz

Time as Geometric Mean of N=30 runs
Geometric of all benchmark New / Old: 0.674
  type, length, New Time, Old Time, New Time / Old Time
 fixed,      0,    2.865,     2.72,               1.053
 fixed,      1,    3.567,    2.489,               1.433
 fixed,      2,    2.577,    3.649,               0.706
 fixed,      3,    3.644,    5.983,               0.609
 fixed,      4,    4.211,    6.833,               0.616
 fixed,      5,    4.741,    9.372,               0.506
 fixed,      6,    5.415,    9.561,               0.566
 fixed,      7,    6.649,   10.789,               0.616
 fixed,      8,    8.081,   11.808,               0.684
 fixed,      9,    8.427,   12.935,               0.651
 fixed,     10,    8.673,   14.134,               0.614
 fixed,     11,    10.69,   15.408,               0.694
 fixed,     12,   10.789,   16.982,               0.635
 fixed,     13,   12.169,   18.411,               0.661
 fixed,     14,   12.659,   19.914,               0.636
 fixed,     15,   13.526,   21.541,               0.628
 fixed,     16,   14.211,   23.088,               0.616
 fixed,     32,   29.412,   52.722,               0.558
 fixed,     64,    65.41,  142.351,               0.459
 fixed,    128,  138.505,  295.625,               0.469
 fixed,    256,  291.707,  601.983,               0.485
random,      2,   12.698,   12.849,               0.988
random,      4,   16.065,   15.857,               1.013
random,      8,   19.564,   21.105,               0.927
random,     16,   23.919,   26.823,               0.892
random,     32,   31.987,   39.591,               0.808
random,     64,   49.282,   71.487,               0.689
random,    128,    82.23,  145.364,               0.566
random,    256,  152.209,  298.434,                0.51

Co-authored-by: Alexander Monakov <amonakov@ispras.ru>
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Diffstat (limited to 'elf')
-rw-r--r--elf/simple-dl-new-hash.h (renamed from elf/dl-new-hash.h)20
-rw-r--r--elf/tst-dl-hash.c1
2 files changed, 9 insertions, 12 deletions
diff --git a/elf/dl-new-hash.h b/elf/simple-dl-new-hash.h
index 8641bb4196..1437b1bd36 100644
--- a/elf/dl-new-hash.h
+++ b/elf/simple-dl-new-hash.h
@@ -1,4 +1,4 @@
-/* _dl_new_hash for elf symbol lookup
+/* __simple_dl_new_hash for testing true elf symbol lookup.
    Copyright (C) 2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,16 +16,16 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#ifndef _DL_NEW_HASH_H
-#define _DL_NEW_HASH_H 1
+#ifndef _SIMPLE_DL_NEW_HASH_H
+#define _SIMPLE_DL_NEW_HASH_H 1
 
 #include <stdint.h>
-/* For __always_inline.  */
-#include <sys/cdefs.h>
 
-static __always_inline uint32_t
+/* For testing/benchmarking purposes.  Real implementation in
+   sysdeps/generic/dl-new-hash.h.  */
+static uint32_t
 __attribute__ ((unused))
-_dl_new_hash (const char *s)
+__simple_dl_new_hash (const char *s)
 {
   uint32_t h = 5381;
   for (unsigned char c = *s; c != '\0'; c = *++s)
@@ -33,8 +33,4 @@ _dl_new_hash (const char *s)
   return h;
 }
 
-/* For testing/benchmarking purposes.  */
-#define __simple_dl_new_hash _dl_new_hash
-
-
-#endif /* dl-new-hash.h */
+#endif /* simple-dl-new-hash.h */
diff --git a/elf/tst-dl-hash.c b/elf/tst-dl-hash.c
index 8697eb73a0..b21766c63d 100644
--- a/elf/tst-dl-hash.c
+++ b/elf/tst-dl-hash.c
@@ -18,6 +18,7 @@
 
 
 #include <simple-dl-hash.h>
+#include <simple-dl-new-hash.h>
 #include <dl-hash.h>
 #include <dl-new-hash.h>
 #include <support/support.h>