* [PATCH] hash: add riscv vector support for 16-byte key comparison
@ 2026-02-26 6:49 P1erreCashon
2026-02-26 18:31 ` Stephen Hemminger
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: P1erreCashon @ 2026-02-26 6:49 UTC (permalink / raw)
To: Stanislaw Kardach, Bruce Richardson, Yipeng Wang, Sameh Gobriel,
Vladimir Medvedkin
Cc: dev, P1erreCashon, gong-flying
Add RISC-V Vector (RVV) optimized implementation for
rte_hash_k16_cmp_eq() to accelerate 16-byte key comparison
in hash lookup fast path.
The implementation uses RVV vector load and compare
instructions to detect mismatched bytes and reduces
comparison latency on RVV-capable systems.
This patch is co-developed with gong-flying.
Signed-off-by: gong-flying <gongxiaofei24@iscas.ac.cn>
Signed-off-by: P1erreCashon <2022302111412@whu.edu.cn>
---
config/riscv/meson.build | 18 +++++++-
lib/hash/rte_cmp_riscv.h | 93 ++++++++++++++++++++++++++++++++++++++
lib/hash/rte_cuckoo_hash.c | 2 +-
lib/hash/rte_cuckoo_hash.h | 6 ++-
4 files changed, 116 insertions(+), 3 deletions(-)
create mode 100644 lib/hash/rte_cmp_riscv.h
diff --git a/config/riscv/meson.build b/config/riscv/meson.build
index 07d7d9da23..a844faaa7b 100644
--- a/config/riscv/meson.build
+++ b/config/riscv/meson.build
@@ -113,12 +113,28 @@ dpdk_flags = flags_common + vendor_config['flags'] + arch_config.get('flags', []
# apply supported machine args
machine_args = [] # Clear previous machine args
-foreach flag: arch_config['machine_args']
+
+# detect best ISA
+if cc.has_argument('-march=rv64gc_zve64x')
+ machine_args += ['-march=rv64gc_zve64x']
+ dpdk_conf.set('RTE_ARCH_RISCV_VEC', 1)
+ message('Using rv64gc_zve64x')
+else
+ machine_args += ['-march=rv64gc']
+ message('Using rv64gc (fallback)')
+endif
+
+# apply extra tuning flags (like -mtune)
+foreach flag: arch_config.get('machine_args', [])
+ if flag.startswith('-march')
+ continue
+ endif
if cc.has_argument(flag)
machine_args += flag
endif
endforeach
+
# apply flags
foreach flag: dpdk_flags
if flag.length() > 0
diff --git a/lib/hash/rte_cmp_riscv.h b/lib/hash/rte_cmp_riscv.h
new file mode 100644
index 0000000000..7881d17e05
--- /dev/null
+++ b/lib/hash/rte_cmp_riscv.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2015 Intel Corporation
+ */
+
+#include <riscv_vector.h>
+
+/* Functions to compare multiple of 16 byte keys (up to 128 bytes) */
+static inline int
+rte_hash_k16_cmp_eq(const void *key1, const void *key2, size_t key_len __rte_unused)
+{
+ const uint8_t *p1 = (const uint8_t *)key1;
+ const uint8_t *p2 = (const uint8_t *)key2;
+ size_t offset = 0;
+
+ while (offset < 16) {
+ size_t vl = __riscv_vsetvl_e8m1(16 - offset);
+
+ vuint8m1_t v1 = __riscv_vle8_v_u8m1(p1 + offset, vl);
+ vuint8m1_t v2 = __riscv_vle8_v_u8m1(p2 + offset, vl);
+
+ /* find != bytes */
+ vbool8_t neq = __riscv_vmsne_vv_u8m1_b8(v1, v2, vl);
+
+ /* if any byte mismatches, return not equal */
+ if (__riscv_vfirst_m_b8(neq, vl) >= 0)
+ return 1;
+
+ offset += vl;
+ }
+
+ /* all bytes equal */
+ return 0;
+}
+
+static inline int
+rte_hash_k32_cmp_eq(const void *key1, const void *key2, size_t key_len)
+{
+ return rte_hash_k16_cmp_eq(key1, key2, key_len) ||
+ rte_hash_k16_cmp_eq((const char *) key1 + 16,
+ (const char *) key2 + 16, key_len);
+}
+
+static inline int
+rte_hash_k48_cmp_eq(const void *key1, const void *key2, size_t key_len)
+{
+ return rte_hash_k16_cmp_eq(key1, key2, key_len) ||
+ rte_hash_k16_cmp_eq((const char *) key1 + 16,
+ (const char *) key2 + 16, key_len) ||
+ rte_hash_k16_cmp_eq((const char *) key1 + 32,
+ (const char *) key2 + 32, key_len);
+}
+
+static inline int
+rte_hash_k64_cmp_eq(const void *key1, const void *key2, size_t key_len)
+{
+ return rte_hash_k32_cmp_eq(key1, key2, key_len) ||
+ rte_hash_k32_cmp_eq((const char *) key1 + 32,
+ (const char *) key2 + 32, key_len);
+}
+
+static inline int
+rte_hash_k80_cmp_eq(const void *key1, const void *key2, size_t key_len)
+{
+ return rte_hash_k64_cmp_eq(key1, key2, key_len) ||
+ rte_hash_k16_cmp_eq((const char *) key1 + 64,
+ (const char *) key2 + 64, key_len);
+}
+
+static inline int
+rte_hash_k96_cmp_eq(const void *key1, const void *key2, size_t key_len)
+{
+ return rte_hash_k64_cmp_eq(key1, key2, key_len) ||
+ rte_hash_k32_cmp_eq((const char *) key1 + 64,
+ (const char *) key2 + 64, key_len);
+}
+
+static inline int
+rte_hash_k112_cmp_eq(const void *key1, const void *key2, size_t key_len)
+{
+ return rte_hash_k64_cmp_eq(key1, key2, key_len) ||
+ rte_hash_k32_cmp_eq((const char *) key1 + 64,
+ (const char *) key2 + 64, key_len) ||
+ rte_hash_k16_cmp_eq((const char *) key1 + 96,
+ (const char *) key2 + 96, key_len);
+}
+
+static inline int
+rte_hash_k128_cmp_eq(const void *key1, const void *key2, size_t key_len)
+{
+ return rte_hash_k64_cmp_eq(key1, key2, key_len) ||
+ rte_hash_k64_cmp_eq((const char *) key1 + 64,
+ (const char *) key2 + 64, key_len);
+}
diff --git a/lib/hash/rte_cuckoo_hash.c b/lib/hash/rte_cuckoo_hash.c
index 9cf94645f6..159001f2fa 100644
--- a/lib/hash/rte_cuckoo_hash.c
+++ b/lib/hash/rte_cuckoo_hash.c
@@ -357,7 +357,7 @@ rte_hash_create(const struct rte_hash_parameters *params)
* If x86 architecture is used, select appropriate compare function,
* which may use x86 intrinsics, otherwise use memcmp
*/
-#if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64)
+#if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64) || defined(RTE_ARCH_RISCV_VEC)
/* Select function to compare keys */
switch (params->key_len) {
case 16:
diff --git a/lib/hash/rte_cuckoo_hash.h b/lib/hash/rte_cuckoo_hash.h
index a528f1d1a0..b693abcb89 100644
--- a/lib/hash/rte_cuckoo_hash.h
+++ b/lib/hash/rte_cuckoo_hash.h
@@ -21,6 +21,10 @@
#include "rte_cmp_arm64.h"
#endif
+#if defined(RTE_ARCH_RISCV_VEC)
+#include "rte_cmp_riscv.h"
+#endif
+
/* Macro to enable/disable run-time checking of function parameters */
#if defined(RTE_LIBRTE_HASH_DEBUG)
#define RETURN_IF_TRUE(cond, retval) do { \
@@ -34,7 +38,7 @@
#include <rte_hash_crc.h>
#include <rte_jhash.h>
-#if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64)
+#if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64) || defined(RTE_ARCH_RISCV_VEC)
/*
* All different options to select a key compare function,
* based on the key size and custom function.
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] hash: add riscv vector support for 16-byte key comparison
2026-02-26 6:49 [PATCH] hash: add riscv vector support for 16-byte key comparison P1erreCashon
@ 2026-02-26 18:31 ` Stephen Hemminger
2026-02-26 18:32 ` Stephen Hemminger
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2026-02-26 18:31 UTC (permalink / raw)
To: P1erreCashon
Cc: Stanislaw Kardach, Bruce Richardson, Yipeng Wang, Sameh Gobriel,
Vladimir Medvedkin, dev, gong-flying
On Thu, 26 Feb 2026 14:49:38 +0800
P1erreCashon <2022302111412@whu.edu.cn> wrote:
> diff --git a/lib/hash/rte_cmp_riscv.h b/lib/hash/rte_cmp_riscv.h
> new file mode 100644
> index 0000000000..7881d17e05
> --- /dev/null
> +++ b/lib/hash/rte_cmp_riscv.h
> @@ -0,0 +1,93 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2015 Intel Corporation
This patch is not from Intel, and it is not 2015
but correct copyright on new code.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] hash: add riscv vector support for 16-byte key comparison
2026-02-26 6:49 [PATCH] hash: add riscv vector support for 16-byte key comparison P1erreCashon
2026-02-26 18:31 ` Stephen Hemminger
@ 2026-02-26 18:32 ` Stephen Hemminger
2026-02-26 18:44 ` Stephen Hemminger
2026-03-10 6:14 ` sunyuechi
3 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2026-02-26 18:32 UTC (permalink / raw)
To: P1erreCashon
Cc: Stanislaw Kardach, Bruce Richardson, Yipeng Wang, Sameh Gobriel,
Vladimir Medvedkin, dev, gong-flying
On Thu, 26 Feb 2026 14:49:38 +0800
P1erreCashon <2022302111412@whu.edu.cn> wrote:
> +/* Functions to compare multiple of 16 byte keys (up to 128 bytes) */
> +static inline int
> +rte_hash_k16_cmp_eq(const void *key1, const void *key2, size_t key_len __rte_unused)
> +{
> + const uint8_t *p1 = (const uint8_t *)key1;
> + const uint8_t *p2 = (const uint8_t *)key2;
Casts of void * pointers are unnecessary in in C (only in C++)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] hash: add riscv vector support for 16-byte key comparison
2026-02-26 6:49 [PATCH] hash: add riscv vector support for 16-byte key comparison P1erreCashon
2026-02-26 18:31 ` Stephen Hemminger
2026-02-26 18:32 ` Stephen Hemminger
@ 2026-02-26 18:44 ` Stephen Hemminger
2026-03-10 6:14 ` sunyuechi
3 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2026-02-26 18:44 UTC (permalink / raw)
To: P1erreCashon
Cc: Stanislaw Kardach, Bruce Richardson, Yipeng Wang, Sameh Gobriel,
Vladimir Medvedkin, dev, gong-flying
On Thu, 26 Feb 2026 14:49:38 +0800
P1erreCashon <2022302111412@whu.edu.cn> wrote:
> +/* Functions to compare multiple of 16 byte keys (up to 128 bytes) */
> +static inline int
> +rte_hash_k16_cmp_eq(const void *key1, const void *key2, size_t key_len __rte_unused)
> +{
> + const uint8_t *p1 = (const uint8_t *)key1;
> + const uint8_t *p2 = (const uint8_t *)key2;
> + size_t offset = 0;
> +
> + while (offset < 16) {
> + size_t vl = __riscv_vsetvl_e8m1(16 - offset);
> +
> + vuint8m1_t v1 = __riscv_vle8_v_u8m1(p1 + offset, vl);
> + vuint8m1_t v2 = __riscv_vle8_v_u8m1(p2 + offset, vl);
> +
> + /* find != bytes */
> + vbool8_t neq = __riscv_vmsne_vv_u8m1_b8(v1, v2, vl);
> +
> + /* if any byte mismatches, return not equal */
> + if (__riscv_vfirst_m_b8(neq, vl) >= 0)
> + return 1;
> +
> + offset += vl;
> + }
> +
> + /* all bytes equal */
> + return 0;
> +}
> +
Compiling this with godbolt generates much bigger code than simple 64 bit version.
Is it really faster?
int
rte_hash_k16_cmp_eq(const void *key1, const void *key2, size_t key_len __rte_unused)
{
const unaligned_uint64_t *k1 = key1;
const unaligned_uint64_t *k2 = key2;
return !!((k1[0] ^ k2[0]) | (k1[1] ^ k2[1]));
}
rte_hash_k16_cmp_eq:
ld a4,8(a0)
ld a5,0(a0)
ld a2,0(a1)
ld a3,8(a1)
xor a0,a5,a2
xor a4,a4,a3
or a0,a0,a4
snez a0,a0
ret
ricsv_hash_k16_cmp_eq:
li a4,0
li a6,16
li a7,15
.L5:
sub a5,a6,a4
vsetvli a5,a5,e8,m1,ta,ma
add a2,a0,a4
add a3,a1,a4
vle8.v v1,0(a2)
vle8.v v2,0(a3)
add a4,a4,a5
vmsne.vv v1,v1,v2
vfirst.m a5,v1
bge a5,zero,.L6
bleu a4,a7,.L5
li a0,0
ret
.L6:
li a0,1
ret
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] hash: add riscv vector support for 16-byte key comparison
2026-02-26 6:49 [PATCH] hash: add riscv vector support for 16-byte key comparison P1erreCashon
` (2 preceding siblings ...)
2026-02-26 18:44 ` Stephen Hemminger
@ 2026-03-10 6:14 ` sunyuechi
3 siblings, 0 replies; 5+ messages in thread
From: sunyuechi @ 2026-03-10 6:14 UTC (permalink / raw)
To: P1erreCashon
Cc: Stanislaw Kardach, Bruce Richardson, Yipeng Wang, Sameh Gobriel,
Vladimir Medvedkin, dev, gong-flying
There is a conflict in config/riscv/meson.build
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-03-10 6:14 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-26 6:49 [PATCH] hash: add riscv vector support for 16-byte key comparison P1erreCashon
2026-02-26 18:31 ` Stephen Hemminger
2026-02-26 18:32 ` Stephen Hemminger
2026-02-26 18:44 ` Stephen Hemminger
2026-03-10 6:14 ` sunyuechi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox