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

Ning Tian tianning24@iscas.ac.cn
Wed Jul 22 07:03:09 GMT 2026


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 <yuansheng@isrc.iscas.ac.cn>
Co-authored-by: Ning Tian <tianning24@iscas.ac.cn>
---
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


More information about the Libc-alpha mailing list