classify: use AVX-512 to calculate hash on x86 68/33768/4
authorDamjan Marion <damarion@cisco.com>
Wed, 22 Sep 2021 13:28:29 +0000 (15:28 +0200)
committerFlorin Coras <florin.coras@gmail.com>
Thu, 23 Sep 2021 18:15:27 +0000 (18:15 +0000)
Type:improvement
Change-Id: I9f9f16eabf64203db11cd4338948d76ca5e0ef12
Signed-off-by: Damjan Marion <damarion@cisco.com>
src/vnet/classify/vnet_classify.c
src/vnet/classify/vnet_classify.h
src/vppinfra/vector_avx2.h
src/vppinfra/vector_avx512.h

index 7962507..0b819db 100644 (file)
@@ -148,6 +148,7 @@ vnet_classify_new_table (vnet_classify_main_t *cm, const u8 *mask,
   t->match_n_vectors = match_n_vectors;
   t->skip_n_vectors = skip_n_vectors;
   t->entries_per_page = 2;
+  t->load_mask = pow2_mask (match_n_vectors * 2);
 
   t->mheap = clib_mem_create_heap (0, memory_size, 1 /* locked */ ,
                                   "classify");
index baeaeaf..65bcc3f 100644 (file)
@@ -162,6 +162,7 @@ typedef struct
   u32 entries_per_page;
   u32 skip_n_vectors;
   u32 match_n_vectors;
+  u16 load_mask;
 
   /* Index of next table to try */
   u32 next_table_index;
@@ -254,7 +255,33 @@ vnet_classify_hash_packet_inline (vnet_classify_table_t *t, const u8 *h)
   ASSERT (t);
   h += t->skip_n_vectors * 16;
 
-#if defined(CLIB_HAVE_VEC128)
+#if defined(CLIB_HAVE_VEC512) && defined(CLIB_HAVE_VEC512_MASK_LOAD_STORE)
+  u64x8 xor_sum_x8, *mask = (u64x8 *) t->mask;
+  u16 load_mask = t->load_mask;
+  u64x8u *data = (u64x8u *) h;
+
+  xor_sum_x8 = u64x8_mask_load_zero (data, load_mask) & mask[0];
+
+  if (PREDICT_FALSE (load_mask >> 8))
+    xor_sum_x8 ^= u64x8_mask_load_zero (data + 1, load_mask >> 8) & mask[1];
+
+  xor_sum_x8 ^= u64x8_align_right (xor_sum_x8, xor_sum_x8, 4);
+  xor_sum_x8 ^= u64x8_align_right (xor_sum_x8, xor_sum_x8, 2);
+  xor_sum = xor_sum_x8[0] ^ xor_sum_x8[1];
+#elif defined(CLIB_HAVE_VEC256) && defined(CLIB_HAVE_VEC256_MASK_LOAD_STORE)
+  u64x4 xor_sum_x4, *mask = (u64x4 *) t->mask;
+  u16 load_mask = t->load_mask;
+  u64x4u *data = (u64x4u *) h;
+
+  xor_sum_x4 = u64x4_mask_load_zero (data, load_mask) & mask[0];
+  xor_sum_x4 ^= u64x4_mask_load_zero (data + 1, load_mask >> 4) & mask[1];
+
+  if (PREDICT_FALSE (load_mask >> 8))
+    xor_sum_x4 ^= u64x4_mask_load_zero (data + 2, load_mask >> 8) & mask[2];
+
+  xor_sum_x4 ^= u64x4_align_right (xor_sum_x4, xor_sum_x4, 2);
+  xor_sum = xor_sum_x4[0] ^ xor_sum_x4[1];
+#elif defined(CLIB_HAVE_VEC128)
   u64x2 *mask = (u64x2 *) t->mask;
   u64x2u *data = (u64x2u *) h;
   u64x2 xor_sum_x2;
index f38a3bd..7226c23 100644 (file)
@@ -192,6 +192,9 @@ u8x32_shuffle (u8x32 v, u8x32 m)
 #define u8x32_align_right(a, b, imm) \
   (u8x32) _mm256_alignr_epi8 ((__m256i) a, (__m256i) b, imm)
 
+#define u64x4_align_right(a, b, imm)                                          \
+  (u64x4) _mm256_alignr_epi64 ((__m256i) a, (__m256i) b, imm)
+
 static_always_inline u32
 u32x8_sum_elts (u32x8 sum8)
 {
index 5da4901..a82231a 100644 (file)
@@ -205,6 +205,9 @@ u8x64_shuffle (u8x64 v, u8x64 m)
 #define u8x64_align_right(a, b, imm) \
   (u8x64) _mm512_alignr_epi8 ((__m512i) a, (__m512i) b, imm)
 
+#define u64x8_align_right(a, b, imm)                                          \
+  (u64x8) _mm512_alignr_epi64 ((__m512i) a, (__m512i) b, imm)
+
 static_always_inline u32
 u32x16_sum_elts (u32x16 sum16)
 {