optimize StringPiece::find(char) for RISC-V with RVV memchr#3396
Open
Felix-Gong wants to merge 4 commits into
Open
optimize StringPiece::find(char) for RISC-V with RVV memchr#3396Felix-Gong wants to merge 4 commits into
Felix-Gong wants to merge 4 commits into
Conversation
This patch adds RVV-accelerated memcmp for StringPiece operations
on RISC-V 64-bit platforms.
The implementation follows glibc's official RVV pattern:
- e8m8 LMUL for maximum throughput
- Hardware-adaptive vector length via vsetvl
- vfirst.m for early-out on first difference
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)
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 implementation
- src/butil/strings/string_piece.h: RVV dispatch in wordmemcmp (N >= 16)
- BUILD.bazel: added string_compare_rvv.cc to BUTIL_SRCS
- CMakeLists.txt: added string_compare_rvv.cc
Signed-off-by: Xiaofei Gong <gongxiaofei24@iscas.ac.cn>
Signed-off-by: YuanSheng <yuansheng@isrc.iscas.ac.cn>
This patch adds RVV-accelerated memcmp for StringPiece operations
on RISC-V 64-bit platforms.
The implementation follows glibc's official RVV pattern:
- e8m8 LMUL for maximum throughput
- Hardware-adaptive vector length via vsetvl
- vfirst.m for early-out on first difference
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)
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 implementation
- src/butil/strings/string_piece.h: RVV dispatch in wordmemcmp (N >= 16)
- BUILD.bazel: added string_compare_rvv.cc to BUTIL_SRCS
- CMakeLists.txt: added string_compare_rvv.cc
Signed-off-by: Xiaofei Gong <gongxiaofei24@iscas.ac.cn>
Signed-off-by: YuanSheng <yuansheng@isrc.iscas.ac.cn>
Add RVV-accelerated rvv_memchr() for byte search in StringPiece::find(char). Uses RVV vector compare + vfirst to scan for target byte, achieving 2.9x-5.8x speedup over glibc memchr on RISC-V SG2044 across 64B-1MB buffer sizes. Signed-off-by: Xiaofei Gong <gongxiaofei24@iscas.ac.cn> Signed-off-by: YuanSheng <yuansheng@isrc.iscas.ac.cn> Signed-off-by: Felix-Gong <gongxiaofei24@iscas.ac.cn>
Contributor
There was a problem hiding this comment.
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 alongsidervv_memcmp()insrc/butil/string_compare_rvv.cc. - Expose RVV helpers in
string_piece.hand dispatchStringPiece::find(char)torvv_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 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 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; |
Contributor
|
LGTM |
… cast - Restore modp_b64_rvv.cc in BUILD.bazel: modp_b64.cc calls rvv_modp_b64_encode/decode when RVV is enabled, so the RVV implementation file must be compiled. - Update file header in string_compare_rvv.cc to mention memchr. - Add explicit size_t cast for pointer difference in string_piece.cc. Signed-off-by: Xiaofei Gong <gongxiaofei24@iscas.ac.cn> Signed-off-by: YuanSheng <yuansheng@isrc.iscas.ac.cn> Signed-off-by: Felix-Gong <gongxiaofei24@iscas.ac.cn>
Felix-Gong
force-pushed
the
riscv-stringpiece-memchr
branch
from
July 21, 2026 03:12
85d8403 to
cb23e48
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this PR does
Adds RVV-accelerated
rvv_memchr()for byte search inStringPiece::find(char)on RISC-V.Implementation
rvv_memchr()instring_compare_rvv.cc: uses RVV vector compare (vmseq) +vfirstto scan for target byte across bufferstring_piece.hwithBUTIL_EXPORTfor shared library buildsstring_piece.cc::find(const StringPiece, char, size_t)— routes torvv_memchr()when RVV available, falls back to genericfindT()otherwisePerformance (RISC-V SG2044, 50000 iterations)
Dependency
Depends on #3390 (RVV memcmp for StringPiece) being merged first, as this branch is based on top of it.
Tests