In all fairness it needs to be said that the libc's implementation has to consider portability to more "exotic" architectures. For example, not every CPU allows to make unaligned 32-bit or 64-bit writes, or it takes a huge penalty for such writes.
pi@rasppi400:~/memset_benchmark $ uname -a
Linux rasppi400 5.10.63-v8+ #1459 SMP PREEMPT Wed Oct 6 16:42:49 BST 2021 aarch64 GNU/Linux
pi@rasppi400:~/memset_benchmark $ ./bench_memset
size, alignment, offset, libc, local
0, 16, 0, 1237452, 834116, 1.483549,
1, 16, 0, 1612697, 945325, 1.705971,
2, 16, 0, 1779538, 945320, 1.882472,
3, 16, 0, 1557081, 945324, 1.647140,
4, 16, 0, 1779527, 889736, 2.000062,
5, 16, 0, 1557103, 1000940, 1.555641,
6, 16, 0, 1779551, 1000944, 1.777873,
7, 16, 0, 1557111, 1000945, 1.555641,
8, 16, 0, 1334654, 889723, 1.500078,
Bus error
pi@rasppi400:~/memset_benchmark $ gdb ./bench_memset
[...]
(gdb) run
Starting program: /home/pi/memset_benchmark/bench_memset
size, alignment, offset, libc, local
0, 16, 0, 1557105, 722928, 2.153887,
1, 16, 0, 1557103, 889797, 1.749953,
2, 16, 0, 1557107, 889849, 1.749855,
3, 16, 0, 1557108, 889759, 1.750033,
4, 16, 0, 1557117, 889789, 1.749985,
5, 16, 0, 1557110, 889745, 1.750063,
6, 16, 0, 1557116, 889754, 1.750052,
7, 16, 0, 1557110, 889758, 1.750038,
8, 16, 0, 1557109, 889803, 1.749948,
Program received signal SIGBUS, Bus error.
small_memset (n=<optimized out>, c=<optimized out>, s=0x29690)
at /home/pi/memset_benchmark/src/lib.c:33
33 *((uint64_t *)last) = val8;On SPARC you have no choice, align or die!
pi@rasppi400:~/memset_benchmark $ uname -a
Linux rasppi400 5.10.63-v8+ #1459 SMP PREEMPT Wed Oct 6 16:42:49 BST 2021 aarch64 GNU/Linux
pi@rasppi400:~/memset_benchmark $
pi@rasppi400:~/memset_benchmark $ file ./bench_memset
./bench_memset: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=ebeb69b6cb9664d78c1256a2c862f3d28f11e15e, with debug_info, not stripped Program received signal SIGBUS, Bus error.
small_memset (n=<optimized out>, c=<optimized out>, s=0x29690)
at /home/pi/memset_benchmark/src/lib.c:33
33 *((uint64_t *)last) = val8;
1: x/i $pc
=> 0x11c8c <local_memset+1560>: strd r0, [r7, #-8]
(gdb) info registers
r0 0x0 0
r1 0x0 0
r2 0x0 0
r3 0x1475 5237
r4 0x5f5e100 100000000
r5 0x11674 71284
r6 0x29690 169616
r7 0x29699 169625https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/aar...
There's also the "ifunc" mechanism which can be used to make the choice at runtime, eg:
https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/aar...