This is an automated email from the ASF dual-hosted git repository.

chenBright pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brpc.git


The following commit(s) were added to refs/heads/master by this push:
     new d026d69b Optimize StringPiece memcmp for RISC-V with RVV (#3390)
d026d69b is described below

commit d026d69be06d11f27d5fe568b83ce36427abc984
Author: Felix-Gong <[email protected]>
AuthorDate: Wed Jul 22 11:19:10 2026 +0800

    Optimize StringPiece memcmp for RISC-V with RVV (#3390)
    
    * optimize StringPiece memcmp for RISC-V with RVV
    
    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 <[email protected]>
    Signed-off-by: YuanSheng <[email protected]>
    
    * optimize StringPiece memcmp for RISC-V with RVV
    
    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 <[email protected]>
    Signed-off-by: YuanSheng <[email protected]>
    
    * add string_compare_rvv.cc to Makefile BUTIL_SOURCES
    
    ---------
    
    Signed-off-by: Xiaofei Gong <[email protected]>
    Signed-off-by: YuanSheng <[email protected]>
---
 BUILD.bazel                      |  2 +-
 CMakeLists.txt                   |  1 +
 Makefile                         |  1 +
 src/butil/string_compare_rvv.cc  | 55 ++++++++++++++++++++++++++++++++++++++++
 src/butil/strings/string_piece.h | 10 ++++++++
 5 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/BUILD.bazel b/BUILD.bazel
index 3a503084..cf4560b7 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -128,7 +128,6 @@ BUTIL_SRCS = [
     "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",
     "src/butil/third_party/snappy/snappy-sinksource.cc",
@@ -189,6 +188,7 @@ BUTIL_SRCS = [
     "src/butil/strings/string_number_conversions.cc",
     "src/butil/strings/string_split.cc",
     "src/butil/strings/string_piece.cc",
+    "src/butil/string_compare_rvv.cc",
     "src/butil/strings/string_util.cc",
     "src/butil/strings/string_util_constants.cc",
     "src/butil/strings/stringprintf.cc",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 20c23141..915b7d29 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -490,6 +490,7 @@ set(BUTIL_SOURCES
     ${PROJECT_SOURCE_DIR}/src/butil/strings/string_number_conversions.cc
     ${PROJECT_SOURCE_DIR}/src/butil/strings/string_split.cc
     ${PROJECT_SOURCE_DIR}/src/butil/strings/string_piece.cc
+    ${PROJECT_SOURCE_DIR}/src/butil/string_compare_rvv.cc
     ${PROJECT_SOURCE_DIR}/src/butil/strings/string_util.cc
     ${PROJECT_SOURCE_DIR}/src/butil/strings/string_util_constants.cc
     ${PROJECT_SOURCE_DIR}/src/butil/strings/stringprintf.cc
diff --git a/Makefile b/Makefile
index b66c464b..86de3884 100644
--- a/Makefile
+++ b/Makefile
@@ -122,6 +122,7 @@ BUTIL_SOURCES = \
     src/butil/strings/string_number_conversions.cc \
     src/butil/strings/string_split.cc \
     src/butil/strings/string_piece.cc \
+    src/butil/string_compare_rvv.cc \
     src/butil/strings/string_util.cc \
     src/butil/strings/string_util_constants.cc \
     src/butil/strings/stringprintf.cc \
diff --git a/src/butil/string_compare_rvv.cc b/src/butil/string_compare_rvv.cc
new file mode 100644
index 00000000..3f7985e1
--- /dev/null
+++ b/src/butil/string_compare_rvv.cc
@@ -0,0 +1,55 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+// 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
+
+#include "butil/strings/string_piece.h"
+
+#if defined(__riscv) && defined(__riscv_vector)
+#include <riscv_vector.h>
+
+namespace butil {
+
+int rvv_memcmp(const void* p1, const void* p2, size_t n) {
+    const uint8_t* src1 = static_cast<const uint8_t*>(p1);
+    const uint8_t* src2 = static_cast<const uint8_t*>(p2);
+    size_t remaining = n;
+
+    while (remaining > 0) {
+        size_t vl = __riscv_vsetvl_e8m8(remaining);
+        vuint8m8_t v1 = __riscv_vle8_v_u8m8(src1, vl);
+        vuint8m8_t v2 = __riscv_vle8_v_u8m8(src2, vl);
+        vbool1_t neq = __riscv_vmsne_vv_u8m8_b1(v1, v2, vl);
+        long first = __riscv_vfirst_m_b1(neq, vl);
+
+        if (first >= 0) {
+            return static_cast<int>(src1[first]) - 
static_cast<int>(src2[first]);
+        }
+
+        src1 += vl;
+        src2 += vl;
+        remaining -= vl;
+    }
+    return 0;
+}
+
+}  // namespace butil
+
+#endif  // __riscv && __riscv_vector
diff --git a/src/butil/strings/string_piece.h b/src/butil/strings/string_piece.h
index dbfd69e6..b1a4ed73 100644
--- a/src/butil/strings/string_piece.h
+++ b/src/butil/strings/string_piece.h
@@ -43,6 +43,11 @@
 
 namespace butil {
 
+// RVV-accelerated byte comparison (implemented in string_compare_rvv.cc)
+#if defined(__riscv) && defined(__riscv_vector)
+BUTIL_EXPORT int rvv_memcmp(const void* p1, const void* p2, size_t n);
+#endif
+
 template <typename STRING_TYPE> class BasicStringPiece;
 typedef BasicStringPiece<std::string> StringPiece;
 typedef BasicStringPiece<string16> StringPiece16;
@@ -286,6 +291,11 @@ template <typename STRING_TYPE> class BasicStringPiece {
   static int wordmemcmp(const value_type* p,
                         const value_type* p2,
                         size_type N) {
+#if defined(__riscv) && defined(__riscv_vector)
+    if (sizeof(value_type) == 1 && N >= 16) {
+      return rvv_memcmp(p, p2, N);
+    }
+#endif
     return STRING_TYPE::traits_type::compare(p, p2, N);
   }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to