From 9775bcac7af1dc837de511193c2daab8e0c8d305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=91=E7=B4=AB=E9=98=B310295048?= Date: Fri, 3 Jul 2026 11:25:02 +0800 Subject: [PATCH] =?UTF-8?q?RISC-V=EF=BC=9AOptimize=20decompression=20throu?= =?UTF-8?q?ghput=20by=20mirroring=20AVX=20fast-path=20for=20RVV=20short=20?= =?UTF-8?q?memcpy=20+15%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- snappy.cc | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/snappy.cc b/snappy.cc index 9826151..1e315a1 100644 --- a/snappy.cc +++ b/snappy.cc @@ -1251,24 +1251,21 @@ void MemCopy64(char* dst, const void* src, size_t size) { _mm256_storeu_si256(reinterpret_cast<__m256i *>(dst) + 1, data); } // RVV acceleration available on RISC-V when compiled with -march=rv64gcv + // RVV: mirror the AVX path — first 32 B, then another 32 B if size > 32. + // e8m1 may need two segments per 32 B when VLEN < 256 (e.g. vl=16 on VLEN=128). #elif defined(__riscv) && SNAPPY_HAVE_RVV - // Cast pointers to the type we will operate on. - unsigned char* dst_ptr = reinterpret_cast(dst); - const unsigned char* src_ptr = reinterpret_cast(src); - size_t remaining_bytes = size; - // Loop as long as there are bytes remaining to be copied. - while (remaining_bytes > 0) { - // Set vector configuration: e8 (8-bit elements), m2 (LMUL=2). - // Use e8m2 configuration to maximize throughput. - size_t vl = VSETVL_E8M2(remaining_bytes); - // Load data from the current source pointer. - vuint8m2_t vec = VLE8_V_U8M2(src_ptr, vl); - // Store data to the current destination pointer. - VSE8_V_U8M2(dst_ptr, vec, vl); - // Update pointers and the remaining count. - src_ptr += vl; - dst_ptr += vl; - remaining_bytes -= vl; + assert(kShortMemCopy <= 32); + const size_t vl = VSETVL_E8M2(32); + unsigned char* d = reinterpret_cast(dst); + const unsigned char* s = reinterpret_cast(src); + vuint8m2_t v0 = VLE8_V_U8M2(s, vl); + VSE8_V_U8M2(d, v0, vl); + // Profiling shows that nearly all copies are short. + if (SNAPPY_PREDICT_FALSE(size > kShortMemCopy)) { + const unsigned char* s2 = s + kShortMemCopy; + unsigned char* d2 = d + kShortMemCopy; + vuint8m2_t v2 = VLE8_V_U8M2(s2, vl); + VSE8_V_U8M2(d2, v2, vl); } #else