riscv: Use LMUL=8 for RVV strchr

Message ID 178334245339.2172208.15795941918027077548@iscas.ac.cn (mailing list archive)
State New
Headers
Series riscv: Use LMUL=8 for RVV strchr |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Build passed
redhat-pt-bot/TryBot-32bit success Build for i686
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 fail Test failed
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Test passed

Commit Message

Ning Tian July 6, 2026, 12:54 p.m. UTC
  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 128 bytes on VLEN=128 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.

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

Signed-off-by: Ning Tian <tianning24@iscas.ac.cn>
---
 sysdeps/riscv/rvv/strchr.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
  

Comments

Peter Bergner July 6, 2026, 2:08 p.m. UTC | #1
On 7/6/26 7:54 AM, Ning Tian wrote:
> 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 128 bytes on VLEN=128 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.


First off, we are currently in a freeze for the upcoming release, so this
will have to wait until after the release (~Aug 1st).

Secondly, these routines are supposed to work on a wide range of riscv
hardware.  Before making a change like this, I'd like some performance numbers
from other systems.  Preferably the recently available K3.  I do not yet
have access to a K3, so maybe you or someone else can test it there?
If it's a win on the K3, then I'm fine with the change....after the release.

Peter
  

Patch

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