From f9dc2729215a1b485150150bd2315caa9710e8e5 Mon Sep 17 00:00:00 2001 From: Xiaofei Gong Date: Tue, 7 Jul 2026 15:06:18 +0000 Subject: [PATCH] iobuf: add RISC-V Vector (RVV) optimized memcpy for cp() Add a RVV-accelerated cp() path for RISC-V 64-bit systems with the Vector (RVV) extension. Uses VL-agnostic intrinsics with LMUL=8 (e8m8) for maximum vector width. Key design: - Falls back to memcpy for < 64 bytes (RVV overhead threshold) - VL-agnostic: works with any VLEN (128/256/512/1024+) - Uses __has_include for compiler compatibility - Guarded by __riscv && __riscv_vector && header availability On SG2044 (rv64gcv, VLEN=128): vectorized copy processes 128 bytes per iteration with e8m8 LMUL. Other platforms and compilers without riscv_vector.h fall back to the existing memcpy path. Signed-off-by: Xiaofei Gong Signed-off-by: YuanSheng --- src/butil/iobuf.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/butil/iobuf.cpp b/src/butil/iobuf.cpp index 01469e2262..a743f7928f 100644 --- a/src/butil/iobuf.cpp +++ b/src/butil/iobuf.cpp @@ -179,9 +179,40 @@ inline iov_function get_pwritev_func() { #endif // ARCH_CPU_X86_64 +#if defined(__riscv) && defined(__riscv_vector) && __has_include() +#include + +// RVV-optimized memory copy using VL-agnostic intrinsics. +// Uses largest available LMUL (e8m8) for maximum vector width. +// Falls back to memcpy for small copies (< 64 bytes). +static inline void* cp_rvv(void* __restrict dest, const void* __restrict src, + size_t n) { + if (n < 64) { + return memcpy(dest, src, n); + } + char* d = static_cast(dest); + const char* s = static_cast(src); + size_t vl; + for (size_t i = 0; i < n; i += vl) { + vl = __riscv_vsetvl_e8m8(n - i); + vuint8m8_t data = + __riscv_vle8_v_u8m8( + reinterpret_cast(s + i), vl); + __riscv_vse8_v_u8m8( + reinterpret_cast(d + i), data, vl); + } + return dest; +} +#define HAS_RVV_CP +#endif + void* cp(void *__restrict dest, const void *__restrict src, size_t n) { +#if defined(HAS_RVV_CP) + return cp_rvv(dest, src, n); +#else // memcpy in gcc 4.8 seems to be faster enough. return memcpy(dest, src, n); +#endif } // Function pointers to allocate or deallocate memory for a IOBuf::Block