nuttx/libs/libc
Justin Hammond 0790b52e64 libs/libc/machine/risc-v: Compare a register at a time on equal offsets.
memcmp, strncmp and strcmp reach their word loops only when both pointers
are already on a register boundary:

  or    t0, a0, a1
  andi  t0, t0, SZREG-1

That asks more than the loops need.  They load from the two pointers at
the same boundary, so what matters is that the two agree about where a
boundary falls, not that either is already on one.  A pair offset by the
same amount can be walked up to the boundary a byte at a time and
compared a register at a time from there.

The union also holds far less often than the difference.  For arbitrary
pointers on RV64 it is true about one time in 64 against one in eight,
and the case it rejects, two strings carved out of the same buffer, is
the common one.

Test the difference of the pointers, and walk to the boundary first.
arch_strcpy.S and arch_memcpy.S already do this.  Keeping every access
aligned is not only faster here: the base ISA does not require misaligned
loads and stores to be supported at all, so a routine in a machine
directory cannot assume one will work, whatever it costs.

Measured on a 1.4 GHz rv64, source and destination misaligned by one:

                    before   after
  memcmp 32K          34.4   458.0 MB/s
  strncmp 32K         32.4   253.0 MB/s
  strcmp 32K          41.0   280.0 MB/s

Each of those was the rate of the byte loop the word loop was meant to
replace.  Pointers that genuinely disagree still take the byte loop, and
the aligned rates are unchanged.

The measurements come from the benchmark in apache/nuttx-apps#3706.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-08-17 12:24:06 +02:00
..
aio
assert
audio
builtin libc/builtin: support per-application priority/stacksize under KERNEL build. 2026-07-13 15:23:39 -03:00
ctype
dirent
dlfcn libc/dlfcn: Count opens so a library can be shared. 2026-08-04 11:12:49 -03:00
elf cmake: Use NUTTX(_DIR/_BIN_DIR) instead CMAKE(_SRC_DIR/_BIN_DIR) 2026-08-09 11:13:08 -03:00
errno
eventfd
fdt cmake: Use NUTTX(_DIR/_BIN_DIR) instead CMAKE(_SRC_DIR/_BIN_DIR) 2026-08-09 11:13:08 -03:00
fixedmath
gdbstub
gnssutils cmake: Use NUTTX(_DIR/_BIN_DIR) instead CMAKE(_SRC_DIR/_BIN_DIR) 2026-08-09 11:13:08 -03:00
grp libs/libc/grp: fix getgrbuf_r() pointer-alignment padding 2026-08-14 10:20:52 +08:00
hex2bin
inttypes
libgen
locale
lzf
machine libs/libc/machine/risc-v: Compare a register at a time on equal offsets. 2026-08-17 12:24:06 +02:00
misc libc/crc32: add IEEE-compatible crc32_ieee for Linux/zlib interop 2026-07-03 10:18:28 +08:00
net
netdb libs/libc/netdb: Size an answer header by its header, not by its union. 2026-08-08 15:02:15 -03:00
obstack
pthread arch, sched/signal: Fix compilation with ENABLE_PARTIAL_SIGNALS=y 2026-06-16 17:07:32 +08:00
pwd sched: add supplementary group IDs (setgroups/getgroups/initgroups) 2026-08-12 16:06:03 -03:00
queue
regex
sched
search
semaphore sched/semaphore: Keep a negative task id out of the mutex holder. 2026-08-09 10:05:30 +08:00
signal
spawn spawn: allow zero stacksize/priority to use binary loader defaults 2026-07-15 12:24:44 -03:00
stdio !include/fcntl.h: align open flags with Linux values 2026-06-30 13:43:44 +08:00
stdlib libs/libc: support explicit bases up to 36 2026-08-01 20:08:32 +08:00
stream libc/stream: Check lowout bounds before access 2026-07-06 09:02:22 +02:00
string libs/libc/string: Add 4-byte alignment middle path for BSD functions. 2026-08-17 10:47:33 +02:00
symtab libs/libc/symtab: fix bogus symbol size under SYMTAB_ORDEREDBYNAME 2026-08-05 21:51:25 +08:00
syslog
termios drivers/serial: add job-control TTY ioctls and libc wrappers 2026-06-23 16:26:53 -03:00
time libc/time: Fix POSIX timezone string parsing. 2026-07-25 19:54:18 +08:00
tls
uio
unistd libc: add wait4() 2026-08-14 10:20:52 +08:00
userfs
uuid
wchar
wctype
wqueue
zoneinfo tools: fix stale archive members surviving a Kconfig-driven CSRCS change 2026-07-28 21:26:03 -03:00
.gitignore
CMakeLists.txt
Kconfig
libc.csv !sched/arch/libc: Give fork() and vfork() their real, separate semantics. 2026-08-10 08:57:30 -03:00
libc.h libs/libc/string: Add 4-byte alignment middle path for BSD functions. 2026-08-17 10:47:33 +02:00
limits_check.c libs/libc: add limits checks 2026-07-02 09:02:21 -03:00
Makefile tools: fix stale archive members surviving a Kconfig-driven CSRCS change 2026-07-28 21:26:03 -03:00