[PATCH v2] riscv: Use LMUL=8 for RVV strchr

Ning Tian <[email protected]>
Newsgroups gmane.comp.lib.glibc.alpha
Message-ID <[email protected]>
The RVV strchr implementation currently uses LMUL=1.  On VLEN=128
hardware this processes 16 bytes per iteration, so the fixed cost of
the fault-only-first load, two byte comparisons, two vfirst.m
operations, and scalar branch logic is paid every 16 bytes.

Use LMUL=8 so each iteration processes 8 times as much data: 128
bytes on VLEN=128 systems and 256 bytes on VLEN=256 systems.  The
character-match mask is moved from v9 to v16 because v0-v7 is now
used by the m8 data vector group.  The end-of-string mask remains in
v8.

On Sophgo SG2044 (VLEN=128, GCC 12.3.1), bench-strchr over 445 cases
shows a 4.63x geometric-mean speedup compared with the LMUL=1 RVV
version.  Full-scan cases improve by 5.52x to 8.96x for lengths from
64 to 8192 bytes.  Short strings that complete in the first vector
chunk regress by about 50% because LMUL=8 has higher vector setup cost;
a later scalar fast path can address that case.

On Spacemit X100 (K3, VLEN=256, in-order core, GCC 15.2.0), bench-strchr
over 554 cases shows a 2.49x geometric-mean speedup and a 3.20x
arithmetic-mean speedup compared with the LMUL=1 RVV version.  Of
those cases, 388 improve by more than 5% and 166 regress by more than
5%.  All regressions are for strings shorter than 32 bytes, where the
geometric mean is 0.83x.  Longer strings show the expected improvement:
the geometric mean is 5.16x for 1024-2048 byte strings and 4.63x for
2048-8192 byte strings.

The two systems show the same tradeoff: LMUL=8 increases startup cost
for very short strings, but it substantially reduces loop overhead for
medium and long strings.

Tested on riscv64-linux-gnu (Sophgo SG2044):
  make subdirs=string check
  make -C benchtests objdir=`pwd` bench-build BENCHSET=string-benchset
  bench-strchr: 445 cases, m8 geo mean 4.63x faster than m1 RVV

Benchmarked on riscv64-linux-gnu (Spacemit X100/K3):
  bench-strchr: 554 cases, m8 geo mean 2.49x faster than m1 RVV

Signed-off-by: YuanSheng <[email protected]>
Co-authored-by: Ning Tian <[email protected]>
---
Changes since v1:
  * Add benchmark results from Spacemit X100/K3 (VLEN=256, in-order).
  * Clarify that the same short-string/long-string tradeoff appears
    on both VLEN=128 and VLEN=256 systems.

 sysdeps/riscv/rvv/strchr.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sysdeps/riscv/rvv/strchr.S b/sysdeps/riscv/rvv/strchr.S
index 2fa95c31ba..f14f93a315 100644
--- a/sysdeps/riscv/rvv/strchr.S
+++ b/sysdeps/riscv/rvv/strchr.S
@@ -32,10 +32,10 @@
 #define cur_vl a6
 #define ivl t0
 
-#define ELEM_LMUL_SETTING m1
+#define ELEM_LMUL_SETTING m8
 #define vstr v0
 #define vmask_end v8
-#define vmask_ch v9
+#define vmask_ch v16
 
 ENTRY (STRCHR)
 .option push
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.