0003-v4-Feat-New-COMP_CRC32C-macro-for-AVX512-simplify-code-.patch

application/octet-stream

Filename: 0003-v4-Feat-New-COMP_CRC32C-macro-for-AVX512-simplify-code-.patch
Type: application/octet-stream
Part: 2
Message: RE: Proposal for Updating CRC32C with AVX-512 Algorithm.

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch v4-0003
Subject: [Feat] New COMP_CRC32C macro for AVX512, simplify code some.
File+
configure 1 1
configure.ac 1 1
src/include/port/pg_crc32c.h 7 10
src/port/meson.build 1 0
src/port/pg_crc32c_avx512.c 2 44
From 993837dfa76beec52a41fd54cb44dd77a0f0d6b5 Mon Sep 17 00:00:00 2001
From: Paul Amonson <paul.d.amonson@intel.com>
Date: Tue, 27 Aug 2024 08:26:19 -0700
Subject: [PATCH] [Feat] New COMP_CRC32C macro for AVX512, simplify code some.

Signed-off-by: Paul Amonson <paul.d.amonson@intel.com>
---
 configure                    |  2 +-
 configure.ac                 |  2 +-
 src/include/port/pg_crc32c.h | 17 ++++++-------
 src/port/meson.build         |  1 +
 src/port/pg_crc32c_avx512.c  | 46 ++----------------------------------
 5 files changed, 12 insertions(+), 56 deletions(-)

diff --git a/configure b/configure
index fca02db11d..7dcc4b9f5d 100755
--- a/configure
+++ b/configure
@@ -18114,7 +18114,7 @@ else
 
 $as_echo "#define USE_AVX512_CRC32C_WITH_RUNTIME_CHECK 1" >>confdefs.h
 
-    PG_CRC32C_OBJS="pg_crc32c_avx512.o pg_crc32c_sb8.o pg_crc32c_avx512_choose.o"
+    PG_CRC32C_OBJS="pg_crc32c_avx512.o pg_crc32c_sb8.o pg_crc32c_sse42.o pg_crc32c_avx512_choose.o"
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: AVX 512 with runtime check" >&5
 $as_echo "AVX 512 with runtime check" >&6; }
   else
diff --git a/configure.ac b/configure.ac
index ce68dce9d2..99ab8bd5d6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2215,7 +2215,7 @@ if test x"$USE_SSE42_CRC32C" = x"1"; then
 else
   if test x"$USE_AVX512_CRC32C_WITH_RUNTIME_CHECK" = x"1"; then
     AC_DEFINE(USE_AVX512_CRC32C_WITH_RUNTIME_CHECK, 1, [Define to 1 to use Intel AVX 512 CRC instructions with a runtime check.])
-    PG_CRC32C_OBJS="pg_crc32c_avx512.o pg_crc32c_sb8.o pg_crc32c_avx512_choose.o"
+    PG_CRC32C_OBJS="pg_crc32c_avx512.o pg_crc32c_sb8.o pg_crc32c_sse42.o pg_crc32c_avx512_choose.o"
     AC_MSG_RESULT(AVX 512 with runtime check)
   else
     if test x"$USE_SSE42_CRC32C_WITH_RUNTIME_CHECK" = x"1"; then
diff --git a/src/include/port/pg_crc32c.h b/src/include/port/pg_crc32c.h
index ade06dbcab..3f83d9f815 100644
--- a/src/include/port/pg_crc32c.h
+++ b/src/include/port/pg_crc32c.h
@@ -40,12 +40,12 @@ typedef uint32 pg_crc32c;
 /* The INIT and EQ macros are the same for all implementations. */
 #define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF)
 #define EQ_CRC32C(c1, c2) ((c1) == (c2))
+#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
 
 #if defined(USE_SSE42_CRC32C)
 /* Use Intel SSE4.2 instructions. */
 #define COMP_CRC32C(crc, data, len) \
 	((crc) = pg_comp_crc32c_sse42((crc), (data), (len)))
-#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
 
 extern pg_crc32c pg_comp_crc32c_sse42(pg_crc32c crc, const void *data, size_t len);
 
@@ -53,7 +53,6 @@ extern pg_crc32c pg_comp_crc32c_sse42(pg_crc32c crc, const void *data, size_t le
 /* Use Intel AVX512 instructions. */
 #define COMP_CRC32C(crc, data, len) \
 	((crc) = pg_comp_crc32c_avx512((crc), (data), (len)))
-#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
 
 extern pg_crc32c pg_comp_crc32c_avx512(pg_crc32c crc, const void *data, size_t len);
 
@@ -62,7 +61,6 @@ extern pg_crc32c pg_comp_crc32c_avx512(pg_crc32c crc, const void *data, size_t l
 
 #define COMP_CRC32C(crc, data, len)							\
 	((crc) = pg_comp_crc32c_armv8((crc), (data), (len)))
-#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
 
 extern pg_crc32c pg_comp_crc32c_armv8(pg_crc32c crc, const void *data, size_t len);
 
@@ -71,7 +69,6 @@ extern pg_crc32c pg_comp_crc32c_armv8(pg_crc32c crc, const void *data, size_t le
 
 #define COMP_CRC32C(crc, data, len)							\
 	((crc) = pg_comp_crc32c_loongarch((crc), (data), (len)))
-#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
 
 extern pg_crc32c pg_comp_crc32c_loongarch(pg_crc32c crc, const void *data, size_t len);
 
@@ -82,14 +79,17 @@ extern pg_crc32c pg_comp_crc32c_loongarch(pg_crc32c crc, const void *data, size_
  * they are available.
  */
 #define COMP_CRC32C(crc, data, len) \
-	((crc) = pg_comp_crc32c((crc), (data), (len)))
-#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
+	((crc) = ((len) < 256 ? \
+		pg_comp_crc32c_sse42((crc), (data), (len)) : \
+		pg_comp_crc32c((crc), (data), (len))))
 
 extern pg_crc32c pg_comp_crc32c_sb8(pg_crc32c crc, const void *data, size_t len);
 extern pg_crc32c (*pg_comp_crc32c)(pg_crc32c crc, const void *data, size_t len);
 
 extern pg_crc32c pg_comp_crc32c_avx512(pg_crc32c crc, const void *data, size_t len);
 
+extern pg_crc32c pg_comp_crc32c_sse42(pg_crc32c crc, const void *data, size_t len);
+
 #elif defined(USE_SSE42_CRC32C_WITH_RUNTIME_CHECK) || defined(USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK)
 
 /*
@@ -98,7 +98,6 @@ extern pg_crc32c pg_comp_crc32c_avx512(pg_crc32c crc, const void *data, size_t l
  */
 #define COMP_CRC32C(crc, data, len) \
 	((crc) = pg_comp_crc32c((crc), (data), (len)))
-#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
 
 extern pg_crc32c pg_comp_crc32c_sb8(pg_crc32c crc, const void *data, size_t len);
 extern pg_crc32c (*pg_comp_crc32c) (pg_crc32c crc, const void *data, size_t len);
@@ -121,13 +120,11 @@ extern pg_crc32c pg_comp_crc32c_armv8(pg_crc32c crc, const void *data, size_t le
 #define COMP_CRC32C(crc, data, len) \
 	((crc) = pg_comp_crc32c_sb8((crc), (data), (len)))
 #ifdef WORDS_BIGENDIAN
+#undef FIN_CRC32C
 #define FIN_CRC32C(crc) ((crc) = pg_bswap32(crc) ^ 0xFFFFFFFF)
-#else
-#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
 #endif
 
 extern pg_crc32c pg_comp_crc32c_sb8(pg_crc32c crc, const void *data, size_t len);
-
 #endif
 
 #endif							/* PG_CRC32C_H */
diff --git a/src/port/meson.build b/src/port/meson.build
index 31d50a7a3b..6a796411b4 100644
--- a/src/port/meson.build
+++ b/src/port/meson.build
@@ -87,6 +87,7 @@ replace_funcs_pos = [
   ['pg_crc32c_avx512', 'USE_AVX512_CRC32C'],
   ['pg_crc32c_avx512', 'USE_AVX512_CRC32C_WITH_RUNTIME_CHECK', 'crc'],
   ['pg_crc32c_avx512_choose', 'USE_AVX512_CRC32C_WITH_RUNTIME_CHECK'],
+  ['pg_crc32c_sse42', 'USE_AVX512_CRC32C_WITH_RUNTIME_CHECK', 'crc'],
   ['pg_crc32c_sb8', 'USE_AVX512_CRC32C_WITH_RUNTIME_CHECK'],
   ['pg_crc32c_sb8', 'USE_SSE42_CRC32C_WITH_RUNTIME_CHECK'],
   ['pg_popcount_avx512', 'USE_AVX512_POPCNT_WITH_RUNTIME_CHECK', 'popcnt'],
diff --git a/src/port/pg_crc32c_avx512.c b/src/port/pg_crc32c_avx512.c
index be42a34a73..98353f7e1d 100644
--- a/src/port/pg_crc32c_avx512.c
+++ b/src/port/pg_crc32c_avx512.c
@@ -18,48 +18,6 @@
 
 #include "port/pg_crc32c.h"
 
-/*
- * Process eight bytes of data at a time.
- *
- * NB: We do unaligned accesses here. The Intel architecture allows that,
- * and performance testing didn't show any performance gain from aligning
- * the begin address.
- */
-pg_attribute_no_sanitize_alignment()
-inline static pg_crc32c
-crc32c_fallback(pg_crc32c crc, const uint8 *p, size_t length)
-{
-	const unsigned char *pend = p + length;
-
-	/*
-	 * Process eight bytes of data at a time.
-	 *
-	 * NB: We do unaligned accesses here. The Intel architecture allows that,
-	 * and performance testing didn't show any performance gain from aligning
-	 * the begin address.
-	 */
-	while (p + 8 <= pend)
-	{
-		crc = (uint32)_mm_crc32_u64(crc, *((const uint64 *)p));
-		p += 8;
-	}
-
-	/* Process remaining full four bytes if any */
-	if (p + 4 <= pend)
-	{
-		crc = _mm_crc32_u32(crc, *((const unsigned int *)p));
-		p += 4;
-	}
-
-	/* Process any remaining bytes one at a time. */
-	while (p < pend)
-	{
-		crc = _mm_crc32_u8(crc, *p);
-		p++;
-	}
-
-	return crc;
-}
 
 /*******************************************************************
  * pg_crc32c_avx512(): compute the crc32c of the buffer, where the
@@ -233,7 +191,7 @@ pg_comp_crc32c_avx512(pg_crc32c crc, const void *data, size_t length)
 	}
 
 	/*
-	 * Finish any remaining bytes.
+	 * Finish any remaining bytes with legacy AVX algorithm.
 	 */
-	return crc32c_fallback(crc, input, length);
+	return pg_comp_crc32c_sse42(crc, input, length);
 }
-- 
2.34.1