public inbox for dev@dpdk.org
 help / color / mirror / Atom feed
* [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