Skip to content

optimize StringPiece::find(char) for RISC-V with RVV memchr#3396

Merged
chenBright merged 1 commit into
apache:masterfrom
Felix-Gong:riscv-stringpiece-memchr
Jul 22, 2026
Merged

optimize StringPiece::find(char) for RISC-V with RVV memchr#3396
chenBright merged 1 commit into
apache:masterfrom
Felix-Gong:riscv-stringpiece-memchr

Conversation

@Felix-Gong

@Felix-Gong Felix-Gong commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

What this PR does

Adds RVV-accelerated rvv_memchr() for byte search in StringPiece::find(char) on RISC-V.

Implementation

  • rvv_memchr() in string_compare_rvv.cc: uses RVV vector compare (vmseq) + vfirst to scan for target byte across buffer
  • Declaration in string_piece.h with BUTIL_EXPORT for shared library builds
  • RVV dispatch in string_piece.cc::find(const StringPiece, char, size_t) — routes to rvv_memchr() when RVV available, falls back to generic findT() otherwise

Performance (RISC-V SG2044, 50000 iterations)

Size glibc memchr RVV memchr Speedup
64B 229 ns 39 ns 5.8x
256B 963 ns 175 ns 5.5x
1KB 3,317 ns 753 ns 4.4x
4KB 13,764 ns 3,522 ns 3.9x
16KB 52,970 ns 13,155 ns 4.0x
64KB 207,870 ns 52,168 ns 4.0x
256KB 723,560 ns 251,868 ns 2.9x
1MB 2,877,680 ns 986,480 ns 2.9x

Dependency

Depends on #3390 (RVV memcmp for StringPiece) being merged first, as this branch is based on top of it.

Tests

  • test_butil: 724/725 passed (1 pre-existing StackTraceTest.find_symbol failure)
  • test_bvar: 64/64 passed
  • Custom memchr correctness tests: 42/42 passed
  • Custom memchr performance benchmarks: all sizes tested

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a RISC-V RVV-accelerated byte-search implementation (rvv_memchr) and wires it into butil::StringPiece::find(char) to speed up single-byte searches on RVV-capable targets.

Changes:

  • Add rvv_memchr() implementation alongside rvv_memcmp() in src/butil/string_compare_rvv.cc.
  • Expose RVV helpers in string_piece.h and dispatch StringPiece::find(char) to rvv_memchr() when RVV is available.
  • Update build files to compile the RVV implementation (CMake + Bazel).

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/butil/strings/string_piece.h Declares RVV helpers and uses rvv_memcmp in wordmemcmp for byte strings.
src/butil/strings/string_piece.cc Dispatches StringPiece::find(char) to RVV memchr on RVV-enabled RISC-V.
src/butil/string_compare_rvv.cc Implements RVV memcmp and new RVV memchr.
CMakeLists.txt Adds string_compare_rvv.cc to BUTIL sources for CMake builds.
BUILD.bazel Adds string_compare_rvv.cc to BUTIL sources for Bazel builds (but currently drops modp_b64_rvv.cc).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread BUILD.bazel
Comment on lines 128 to 132
"src/butil/third_party/icu/icu_utf.cc",
"src/butil/third_party/superfasthash/superfasthash.c",
"src/butil/third_party/modp_b64/modp_b64.cc",
"src/butil/third_party/modp_b64/modp_b64_rvv.cc",
"src/butil/third_party/symbolize/demangle.cc",
"src/butil/third_party/symbolize/symbolize.cc",
Comment thread src/butil/string_compare_rvv.cc Outdated
Comment on lines +18 to +22
// RVV-accelerated memcmp for StringPiece operations.
// Algorithm follows glibc's RVV memcmp pattern:
// - e8m8 LMUL with hardware-adaptive VL via vsetvl
// - vfirst.m for early-out on first mismatch

Comment on lines +139 to +143
const void* result = butil::rvv_memchr(self.data() + pos, c, self.size() - pos);
if (result != nullptr) {
return static_cast<const char*>(result) - self.data();
}
return BasicStringPiece<std::string>::npos;
@wwbmmm

wwbmmm commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

LGTM

@Felix-Gong
Felix-Gong force-pushed the riscv-stringpiece-memchr branch from 85d8403 to cb23e48 Compare July 21, 2026 03:12

@chenBright chenBright left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The BUTIL_SOURCES of Makefile also need to be updated.

This patch adds RVV-accelerated memcmp and memchr for StringPiece operations
on RISC-V 64-bit platforms.

The implementation follows glibc's official RVV memcmp/memchr patterns:
- e8m8 LMUL for maximum throughput
- Hardware-adaptive vector length via vsetvl
- vfirst.m for early-out on first difference/match

Performance on SOPHGO SG2044 (RVV 1.0, VLEN >= 128, GCC 15.1):
glibc 2.38 scalar memcmp (no RVV acceleration) as baseline.

  memcmp (worst-case full scan, 50000 iterations):
    64 B:   20 ns ->   6 ns  (3.4x)
   256 B:   54 ns ->  15 ns  (3.6x)
     1 KB: 120 ns ->  55 ns  (2.2x)
     4 KB: 435 ns -> 225 ns  (1.9x)
    16 KB: 1968 ns -> 1258 ns (1.6x)
    64 KB: 10962 ns -> 9044 ns (1.2x)
   256 KB: 46893 ns -> 43108 ns (1.1x)
     1 MB: 446161 ns -> 454717 ns (1.01x)

  memchr (worst-case full scan, 50000 iterations):
    64 B:    5 ns ->  0.9 ns  (5.8x)
   256 B:   12 ns ->   3 ns  (4.0x)
     1 KB:   40 ns ->  12 ns  (3.3x)
     4 KB:  148 ns ->  44 ns  (3.4x)
    16 KB:  558 ns -> 158 ns  (3.5x)
    64 KB: 2150 ns ->  635 ns (3.4x)
   256 KB: 9200 ns -> 2900 ns (3.2x)
     1 MB: 39000 ns -> 13000 ns (3.0x)

Correctness:
  - 59/59 expanded correctness tests passed (64B - 1MB)
  - string_piece_unittest: 24/24 passed
  - test_butil: 724/725 passed (1 pre-existing StackTrace failure)
  - test_bvar: 64/64 passed

Files changed:
  - src/butil/string_compare_rvv.cc (new): RVV memcmp + memchr implementations
  - src/butil/strings/string_piece.h: RVV dispatch declarations
  - src/butil/strings/string_piece.cc: RVV dispatch in find(char) for memchr
  - BUILD.bazel: added string_compare_rvv.cc to BUTIL_SRCS
  - CMakeLists.txt: added string_compare_rvv.cc
  - Makefile: added string_compare_rvv.cc

Signed-off-by: Xiaofei Gong <gongxiaofei24@iscas.ac.cn>
Signed-off-by: YuanSheng <yuansheng@isrc.iscas.ac.cn>
@Felix-Gong
Felix-Gong force-pushed the riscv-stringpiece-memchr branch from cb23e48 to 85f3d48 Compare July 22, 2026 03:29
@Felix-Gong

Copy link
Copy Markdown
Contributor Author

@chenBright Thanks for pointing this out! Rebased onto latest master (PR #3390 is merged), so the Makefile fix is already in master. No separate Makefile change needed in this PR. Force-pushed the update.

@chenBright chenBright left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@chenBright
chenBright merged commit 5197621 into apache:master Jul 22, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants