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 f16ab1c5 snappy: optimize UnalignedCopy64 and IncrementalCopy for 
RISC-V (#3360)
f16ab1c5 is described below

commit f16ab1c581746919fb394c3cfd3735ed83a4e3bc
Author: Felix-Gong <[email protected]>
AuthorDate: Tue Jul 7 15:26:10 2026 +0800

    snappy: optimize UnalignedCopy64 and IncrementalCopy for RISC-V (#3360)
    
    * snappy: optimize UnalignedCopy64 and IncrementalCopy for RISC-V
    
    Use RISC-V inline assembly (ld/sd) for 8-byte copy operations instead
    of generic macro-based implementation.
    
    Changes:
    - UnalignedCopy64: direct ld/sd pair for 8-byte copy
    - IncrementalCopy: 8-byte bulk copies when source/dest don't overlap
    
    Performance improvement (direct function benchmark):
    - Decompress compressible-256K: 728 MB/s -> 2205 MB/s (+203%)
    - Decompress zeros-256K: 543 MB/s -> 1462 MB/s (+169%)
    
    Tests: brpc_snappy_compress_unittest passed (7/7)
    
    Signed-off-by: Xiaofei Gong <[email protected]>
    Signed-off-by: YuanSheng <[email protected]>
    
    * snappy: add alignment check for RISC-V ld/sd optimization
    
    Address Copilot review: ld/sd require 8-byte alignment. Add runtime
    alignment check and fall back to memcpy/byte-copy for unaligned
    addresses to avoid traps on implementations that don't support
    misaligned access.
    
    Signed-off-by: Xiaofei Gong <[email protected]>
    Signed-off-by: YuanSheng <[email protected]>
    
    ---------
    
    Signed-off-by: Xiaofei Gong <[email protected]>
    Signed-off-by: YuanSheng <[email protected]>
---
 .../third_party/snappy/snappy-stubs-internal.h     | 16 +++++++++++++++
 src/butil/third_party/snappy/snappy.cc             | 23 ++++++++++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/src/butil/third_party/snappy/snappy-stubs-internal.h 
b/src/butil/third_party/snappy/snappy-stubs-internal.h
index e94a9c73..764f97bc 100644
--- a/src/butil/third_party/snappy/snappy-stubs-internal.h
+++ b/src/butil/third_party/snappy/snappy-stubs-internal.h
@@ -164,6 +164,21 @@ inline void UNALIGNED_STORE64(void *p, uint64_t v) {
 // This can be more efficient than UNALIGNED_LOAD64 + UNALIGNED_STORE64
 // on some platforms, in particular ARM.
 inline void UnalignedCopy64(const void *src, void *dst) {
+#if defined(__riscv) && __riscv_xlen == 64
+    // RISC-V optimized: single ld/sd pair for 8-byte copy (aligned only)
+    if ((((uintptr_t)src | (uintptr_t)dst) & 7) == 0) {
+        uint64_t tmp;
+        __asm__ volatile(
+            "ld %0, %1\n\t"
+            "sd %0, %2\n\t"
+            : "=&r"(tmp)
+            : "m"(*(const uint64_t*)src), "m"(*(uint64_t*)dst)
+            : "memory");
+    } else {
+        // Unaligned: fall back to memcpy-based approach
+        memcpy(dst, src, 8);
+    }
+#else
     if (sizeof(void *) == 8) {
         UNALIGNED_STORE64(dst, UNALIGNED_LOAD64(src));
     } else {
@@ -173,6 +188,7 @@ inline void UnalignedCopy64(const void *src, void *dst) {
         UNALIGNED_STORE32(dst_char, UNALIGNED_LOAD32(src_char));
         UNALIGNED_STORE32(dst_char + 4, UNALIGNED_LOAD32(src_char + 4));
     }
+#endif
 }
 
 // Convert to little-endian storage, opposite of network format.
diff --git a/src/butil/third_party/snappy/snappy.cc 
b/src/butil/third_party/snappy/snappy.cc
index c42889f8..bcbf39ed 100644
--- a/src/butil/third_party/snappy/snappy.cc
+++ b/src/butil/third_party/snappy/snappy.cc
@@ -97,9 +97,32 @@ static const uint32_t kMaximumTagLength = 5;  // 
COPY_4_BYTE_OFFSET plus the act
 // or memmove().
 static inline void IncrementalCopy(const char* src, char* op, ssize_t len) {
     assert(len > 0);
+#if defined(__riscv) && __riscv_xlen == 64
+    // RISC-V optimized: use 8-byte copies when aligned and safe
+    if (len >= 8 && (op - src >= 8 || src - op >= 8) &&
+        (((uintptr_t)src | (uintptr_t)op) & 7) == 0) {
+        do {
+            uint64_t tmp;
+            __asm__ volatile(
+                "ld %0, %1\n\t"
+                "sd %0, %2\n\t"
+                : "=&r"(tmp)
+                : "m"(*(const uint64_t*)src), "m"(*(uint64_t*)op)
+                : "memory");
+            src += 8;
+            op += 8;
+            len -= 8;
+        } while (len >= 8);
+    }
+    while (len > 0) {
+        *op++ = *src++;
+        --len;
+    }
+#else
     do {
         *op++ = *src++;
     } while (--len > 0);
+#endif
 }
 
 // Equivalent to IncrementalCopy except that it can write up to ten extra


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

Reply via email to