Thread

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Use AVX2 for calculating page checksums where available

  2. Refactor checksumming code to make it easier to use externally.

  1. Re: Proposal for enabling auto-vectorization for checksum calculations

    Andrew Kim <tenistarkim@gmail.com> — 2025-09-11T05:42:18Z

    Hi John,
    
    Thanks for the feedback. This is v5 of the patchset, updated following your comments:
    
    - Moved the function pointer definitions out of common headers and
      into src/port, consistent with existing practice.
    
    Thanks again for the guidance.
    
    Best regards,
    Kim Andrew
    
    
    
    
  2. [PATCH 1/2] Enable autovectorizing pg_checksum_block

    Andrew Kim <tenistarkim@gmail.com> — 2025-09-11T05:42:19Z

    From: Andrew Kim <andrew.kim@intel.com>
    
    ---
     config/c-compiler.m4                |  31 +++++
     configure                           |  52 +++++++++
     configure.ac                        |   9 ++
     meson.build                         |  28 +++++
     src/include/pg_config.h.in          |   3 +
     src/include/storage/checksum_impl.h |  90 +++-----------
     src/port/Makefile                   |   1 +
     src/port/meson.build                |   1 +
     src/port/pg_checksum_dispatch.c     | 174 ++++++++++++++++++++++++++++
     9 files changed, 318 insertions(+), 71 deletions(-)
     create mode 100644 src/port/pg_checksum_dispatch.c
    
    diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
    index da40bd6a647..5eb3218deb5 100644
    --- a/config/c-compiler.m4
    +++ b/config/c-compiler.m4
    @@ -711,6 +711,37 @@ fi
     undefine([Ac_cachevar])dnl
     ])# PGAC_XSAVE_INTRINSICS
     
    +# PGAC_AVX2_SUPPORT
    +# -----------------------------
    +# Check if the compiler supports AVX2 in attribute((target))
    +# and using AVX2 intrinsics in those functions
    +#
    +# If the intrinsics are supported, sets pgac_avx2_support.
    +AC_DEFUN([PGAC_AVX2_SUPPORT],
    +[define([Ac_cachevar], [AS_TR_SH([pgac_cv_avx2_support])])dnl
    +AC_CACHE_CHECK([for AVX2 support], [Ac_cachevar],
    +[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <immintrin.h>
    +    #include <stdint.h>
    +    #if defined(__has_attribute) && __has_attribute (target)
    +    __attribute__((target("avx2")))
    +    #endif
    +    static int avx2_test(void)
    +    {
    +      const char buf@<:@sizeof(__m256i)@:>@;
    +      __m256i accum = _mm256_loadu_si256((const __m256i *) buf);
    +	  accum = _mm256_add_epi32(accum, accum);
    +      int result = _mm256_extract_epi32(accum, 0);
    +      return (int) result;
    +    }],
    +  [return avx2_test();])],
    +  [Ac_cachevar=yes],
    +  [Ac_cachevar=no])])
    +if test x"$Ac_cachevar" = x"yes"; then
    +  pgac_avx2_support=yes
    +fi
    +undefine([Ac_cachevar])dnl
    +])# PGAC_AVX2_SUPPORT
    +
     # PGAC_AVX512_POPCNT_INTRINSICS
     # -----------------------------
     # Check if the compiler supports the AVX-512 popcount instructions using the
    diff --git a/configure b/configure
    index 39c68161cec..54da05ac0db 100755
    --- a/configure
    +++ b/configure
    @@ -17608,6 +17608,58 @@ $as_echo "#define HAVE_XSAVE_INTRINSICS 1" >>confdefs.h
     
     fi
     
    +# Check for AVX2 target and intrinsic support
    +#
    +if test x"$host_cpu" = x"x86_64"; then
    +  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AVX2 support" >&5
    +$as_echo_n "checking for AVX2 support... " >&6; }
    +if ${pgac_cv_avx2_support+:} false; then :
    +  $as_echo_n "(cached) " >&6
    +else
    +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +#include <immintrin.h>
    +    #include <stdint.h>
    +    #if defined(__has_attribute) && __has_attribute (target)
    +    __attribute__((target("avx2")))
    +    #endif
    +    static int avx2_test(void)
    +    {
    +      const char buf[sizeof(__m256i)];
    +      __m256i accum = _mm256_loadu_si256((const __m256i *) buf);
    +	  accum = _mm256_add_epi32(accum, accum);
    +      int result = _mm256_extract_epi32(accum, 0);
    +      return (int) result;
    +    }
    +int
    +main ()
    +{
    +return avx2_test();
    +  ;
    +  return 0;
    +}
    +_ACEOF
    +if ac_fn_c_try_link "$LINENO"; then :
    +  pgac_cv_avx2_support=yes
    +else
    +  pgac_cv_avx2_support=no
    +fi
    +rm -f core conftest.err conftest.$ac_objext \
    +    conftest$ac_exeext conftest.$ac_ext
    +fi
    +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_avx2_support" >&5
    +$as_echo "$pgac_cv_avx2_support" >&6; }
    +if test x"$pgac_cv_avx2_support" = x"yes"; then
    +  pgac_avx2_support=yes
    +fi
    +
    +  if test x"$pgac_avx2_support" = x"yes"; then
    +
    +$as_echo "#define USE_AVX2_WITH_RUNTIME_CHECK 1" >>confdefs.h
    +
    +  fi
    +fi
    +
     # Check for AVX-512 popcount intrinsics
     #
     if test x"$host_cpu" = x"x86_64"; then
    diff --git a/configure.ac b/configure.ac
    index 066e3976c0a..2c484a12671 100644
    --- a/configure.ac
    +++ b/configure.ac
    @@ -2118,6 +2118,15 @@ if test x"$pgac_xsave_intrinsics" = x"yes"; then
       AC_DEFINE(HAVE_XSAVE_INTRINSICS, 1, [Define to 1 if you have XSAVE intrinsics.])
     fi
     
    +# Check for AVX2 target and intrinsic support
    +#
    +if test x"$host_cpu" = x"x86_64"; then
    +  PGAC_AVX2_SUPPORT()
    +  if test x"$pgac_avx2_support" = x"yes"; then
    +    AC_DEFINE(USE_AVX2_WITH_RUNTIME_CHECK, 1, [Define to 1 to use AVX2 instructions with a runtime check.])
    +  fi
    +fi
    +
     # Check for AVX-512 popcount intrinsics
     #
     if test x"$host_cpu" = x"x86_64"; then
    diff --git a/meson.build b/meson.build
    index ab8101d67b2..ff42c41ca7e 100644
    --- a/meson.build
    +++ b/meson.build
    @@ -2289,6 +2289,34 @@ int main(void)
     
     endif
     
    +###############################################################
    +# Check for the availability of AVX2 support
    +###############################################################
    +
    +if host_cpu == 'x86_64'
    +
    +  prog = '''
    +#include <immintrin.h>
    +#include <stdint.h>
    +#if defined(__has_attribute) && __has_attribute (target)
    +__attribute__((target("avx2")))
    +#endif
    +int main(void)
    +{
    +  const char buf[sizeof(__m256i)];
    +  __m256i accum = _mm256_loadu_si256((const __m256i *) buf);
    +  accum = _mm256_add_epi32(accum, accum);
    +  int result = _mm256_extract_epi32(accum, 0);
    +  return (int) result;
    +}
    +'''
    +
    +  if cc.links(prog, name: 'AVX2 support', args: test_c_args)
    +    cdata.set('USE_AVX2_WITH_RUNTIME_CHECK', 1)
    +  endif
    +
    +endif
    +
     
     ###############################################################
     # Check for the availability of AVX-512 popcount intrinsics.
    diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
    index c4dc5d72bdb..987f9b5c77c 100644
    --- a/src/include/pg_config.h.in
    +++ b/src/include/pg_config.h.in
    @@ -675,6 +675,9 @@
     /* Define to 1 to use AVX-512 CRC algorithms with a runtime check. */
     #undef USE_AVX512_CRC32C_WITH_RUNTIME_CHECK
     
    +/* Define to 1 to use AVX2 instructions with a runtime check. */
    +#undef USE_AVX2_WITH_RUNTIME_CHECK
    +
     /* Define to 1 to use AVX-512 popcount instructions with a runtime check. */
     #undef USE_AVX512_POPCNT_WITH_RUNTIME_CHECK
     
    diff --git a/src/include/storage/checksum_impl.h b/src/include/storage/checksum_impl.h
    index da87d61ba52..82e525529f4 100644
    --- a/src/include/storage/checksum_impl.h
    +++ b/src/include/storage/checksum_impl.h
    @@ -101,12 +101,14 @@
      */
     
     #include "storage/bufpage.h"
    +#include "pg_config.h"
     
     /* number of checksums to calculate in parallel */
     #define N_SUMS 32
     /* prime multiplier of FNV-1a hash */
     #define FNV_PRIME 16777619
     
    +
     /* Use a union so that this code is valid under strict aliasing */
     typedef union
     {
    @@ -142,74 +144,20 @@ do { \
      * Block checksum algorithm.  The page must be adequately aligned
      * (at least on 4-byte boundary).
      */
    -static uint32
    -pg_checksum_block(const PGChecksummablePage *page)
    -{
    -	uint32		sums[N_SUMS];
    -	uint32		result = 0;
    -	uint32		i,
    -				j;
    -
    -	/* ensure that the size is compatible with the algorithm */
    -	Assert(sizeof(PGChecksummablePage) == BLCKSZ);
    -
    -	/* initialize partial checksums to their corresponding offsets */
    -	memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets));
    -
    -	/* main checksum calculation */
    -	for (i = 0; i < (uint32) (BLCKSZ / (sizeof(uint32) * N_SUMS)); i++)
    -		for (j = 0; j < N_SUMS; j++)
    -			CHECKSUM_COMP(sums[j], page->data[i][j]);
    -
    -	/* finally add in two rounds of zeroes for additional mixing */
    -	for (i = 0; i < 2; i++)
    -		for (j = 0; j < N_SUMS; j++)
    -			CHECKSUM_COMP(sums[j], 0);
    -
    -	/* xor fold partial checksums together */
    -	for (i = 0; i < N_SUMS; i++)
    -		result ^= sums[i];
    -
    -	return result;
    -}
    -
    -/*
    - * Compute the checksum for a Postgres page.
    - *
    - * The page must be adequately aligned (at least on a 4-byte boundary).
    - * Beware also that the checksum field of the page is transiently zeroed.
    - *
    - * The checksum includes the block number (to detect the case where a page is
    - * somehow moved to a different location), the page header (excluding the
    - * checksum itself), and the page data.
    - */
    -uint16
    -pg_checksum_page(char *page, BlockNumber blkno)
    -{
    -	PGChecksummablePage *cpage = (PGChecksummablePage *) page;
    -	uint16		save_checksum;
    -	uint32		checksum;
    -
    -	/* We only calculate the checksum for properly-initialized pages */
    -	Assert(!PageIsNew((Page) page));
    -
    -	/*
    -	 * Save pd_checksum and temporarily set it to zero, so that the checksum
    -	 * calculation isn't affected by the old checksum stored on the page.
    -	 * Restore it after, because actually updating the checksum is NOT part of
    -	 * the API of this function.
    -	 */
    -	save_checksum = cpage->phdr.pd_checksum;
    -	cpage->phdr.pd_checksum = 0;
    -	checksum = pg_checksum_block(cpage);
    -	cpage->phdr.pd_checksum = save_checksum;
    -
    -	/* Mix in the block number to detect transposed pages */
    -	checksum ^= blkno;
    -
    -	/*
    -	 * Reduce to a uint16 (to fit in the pd_checksum field) with an offset of
    -	 * one. That avoids checksums of zero, which seems like a good idea.
    -	 */
    -	return (uint16) ((checksum % 65535) + 1);
    -}
    +#define PG_DECLARE_CHECKSUM_ISA(ISANAME) \
    +uint32 \
    +pg_checksum_block_##ISANAME(const PGChecksummablePage *page);
    +
    +#define PG_DEFINE_CHECKSUM_ISA(ISANAME) \
    +pg_attribute_target(#ISANAME) \
    +uint32 pg_checksum_block_##ISANAME(const PGChecksummablePage *page) \
    +
    +/* Declare ISA implementations (declarations only in header) */
    +#ifdef USE_AVX2_WITH_RUNTIME_CHECK
    +PG_DECLARE_CHECKSUM_ISA(avx2);
    +#endif
    +PG_DECLARE_CHECKSUM_ISA(default);
    +
    +uint32 pg_checksum_block_dispatch(const PGChecksummablePage *page);
    +extern uint32 (*pg_checksum_block)(const PGChecksummablePage *page);
    +extern uint16 pg_checksum_page(char *page, BlockNumber blkno);
    diff --git a/src/port/Makefile b/src/port/Makefile
    index 4274949dfa4..27423f1058b 100644
    --- a/src/port/Makefile
    +++ b/src/port/Makefile
    @@ -48,6 +48,7 @@ OBJS = \
     	pg_numa.o \
     	pg_popcount_aarch64.o \
     	pg_popcount_avx512.o \
    +	pg_checksum_dispatch.o \
     	pg_strong_random.o \
     	pgcheckdir.o \
     	pgmkdirp.o \
    diff --git a/src/port/meson.build b/src/port/meson.build
    index fc7b059fee5..c4bbe9f2ece 100644
    --- a/src/port/meson.build
    +++ b/src/port/meson.build
    @@ -11,6 +11,7 @@ pgport_sources = [
       'pg_numa.c',
       'pg_popcount_aarch64.c',
       'pg_popcount_avx512.c',
    +  'pg_checksum_dispatch.c',
       'pg_strong_random.c',
       'pgcheckdir.c',
       'pgmkdirp.c',
    diff --git a/src/port/pg_checksum_dispatch.c b/src/port/pg_checksum_dispatch.c
    new file mode 100644
    index 00000000000..15f7b8af34f
    --- /dev/null
    +++ b/src/port/pg_checksum_dispatch.c
    @@ -0,0 +1,174 @@
    +/*-------------------------------------------------------------------------
    + *
    + * pg_checksum_dispatch.c
    + *        Holds the AVX2 pg_popcount() implementation.
    + *
    + * Copyright (c) 2024-2025, PostgreSQL Global Development Group
    + *
    + * IDENTIFICATION
    + *        src/port/pg_checksum_dispatch.c
    + *
    + *-------------------------------------------------------------------------
    + */
    +#include "c.h"
    +#include "storage/checksum_impl.h"
    +
    +#if defined(HAVE__GET_CPUID) || defined(HAVE__GET_CPUID_COUNT)
    +#include <cpuid.h>
    +#endif
    +
    +#ifdef HAVE_XSAVE_INTRINSICS
    +#include <immintrin.h>
    +#endif
    +
    +#if defined(HAVE__CPUID) || defined(HAVE__CPUIDEX)
    +#include <intrin.h>
    +#endif
    +
    +#include "port/pg_bitutils.h"
    +
    +/*
    + * Does CPUID say there's support for XSAVE instructions?
    + */
    +static inline bool
    +xsave_available(void)
    +{
    +	unsigned int exx[4] = {0, 0, 0, 0};
    +
    +#if defined(HAVE__GET_CPUID)
    +	__get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]);
    +#elif defined(HAVE__CPUID)
    +	__cpuid(exx, 1);
    +#elif defined(__x86_64__)
    +#error cpuid instruction not available
    +#endif
    +	return (exx[2] & (1 << 27)) != 0;       /* osxsave */
    +}
    +
    +/*
    + * Does XGETBV say the YMM registers are enabled?
    + *
    + * NB: Caller is responsible for verifying that xsave_available() returns true
    + * before calling this.
    + */
    +#ifdef HAVE_XSAVE_INTRINSICS
    +pg_attribute_target("xsave")
    +#endif
    +static inline bool
    +ymm_regs_available(void)
    +{
    +#ifdef HAVE_XSAVE_INTRINSICS
    +	return (_xgetbv(0) & 0x06) == 0x06;
    +#else
    +	return false;
    +#endif
    +}
    +
    +/*
    + * Does CPUID say there's support for AVX-2
    + */
    +static inline bool
    +avx2_available(void)
    +{
    +#if defined (USE_AVX2_WITH_RUNTIME_CHECK) && defined(__x86_64__)
    +	unsigned int exx[4] = {0, 0, 0, 0};
    +	if (!xsave_available() || !ymm_regs_available()) return false;
    +
    +#if defined(HAVE__GET_CPUID_COUNT)
    +	__get_cpuid_count(7, 0, &exx[0], &exx[1], &exx[2], &exx[3]);
    +#elif defined(HAVE__CPUIDEX)
    +	__cpuidex(exx, 7, 0);
    +#else
    +#error cpuid instruction not available
    +#endif
    +	return (exx[1] & (1 << 5)) != 0; /* avx2 */
    +#else
    +	return false;
    +#endif
    +}
    +
    +
    +/* default checksum implementation */
    +PG_DEFINE_CHECKSUM_ISA(default)
    +{
    +	uint32 sums[N_SUMS], result = 0;
    +	uint32 i, j;
    +
    +	Assert(sizeof(PGChecksummablePage) == BLCKSZ);
    +	memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets));
    +
    +	for (i = 0; i < (uint32)(BLCKSZ / (sizeof(uint32) * N_SUMS)); i++)
    +		for (j = 0; j < N_SUMS; j++)
    +			CHECKSUM_COMP(sums[j], page->data[i][j]);
    +
    +	for (i = 0; i < 2; i++)
    +		for (j = 0; j < N_SUMS; j++)
    +			CHECKSUM_COMP(sums[j], 0);
    +
    +	for (i = 0; i < N_SUMS; i++)
    +		result ^= sums[i];
    +
    +	return result;
    +}
    +
    +#ifdef USE_AVX2_WITH_RUNTIME_CHECK
    +PG_DEFINE_CHECKSUM_ISA(avx2)
    +{
    +	uint32 sums[N_SUMS], result = 0;
    +	uint32 i, j;
    +
    +	Assert(sizeof(PGChecksummablePage) == BLCKSZ);
    +	memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets));
    +
    +	for (i = 0; i < (uint32)(BLCKSZ / (sizeof(uint32) * N_SUMS)); i++)
    +		for (j = 0; j < N_SUMS; j++)
    +			CHECKSUM_COMP(sums[j], page->data[i][j]);
    +
    +	for (i = 0; i < 2; i++)
    +		for (j = 0; j < N_SUMS; j++)
    +			CHECKSUM_COMP(sums[j], 0);
    +
    +	for (i = 0; i < N_SUMS; i++)
    +		result ^= sums[i];
    +
    +	return result;
    +}
    +#endif
    +
    +/* Function pointer - external linkage (declared extern in header) */
    +uint32 (*pg_checksum_block)(const PGChecksummablePage *page) = pg_checksum_block_dispatch;
    +
    +/* Dispatch function: simple, safe */
    +uint32 pg_checksum_block_dispatch(const PGChecksummablePage *page)
    +{
    +#ifdef USE_AVX2_WITH_RUNTIME_CHECK
    +	if (avx2_available())
    +	{
    +		/* optional: patch pointer so next call goes directly */
    +		pg_checksum_block = pg_checksum_block_avx2;
    +		return pg_checksum_block_avx2(page);
    +	}
    +#endif
    +	/* fallback */
    +	pg_checksum_block = pg_checksum_block_default;
    +	return pg_checksum_block_default(page);
    +}
    +
    +
    +/* Compute checksum for a Postgres page */
    +uint16 pg_checksum_page(char *page, BlockNumber blkno)
    +{
    +	PGChecksummablePage *cpage = (PGChecksummablePage *) page;
    +	uint16 save_checksum;
    +	uint32 checksum;
    +
    +	Assert(!PageIsNew((Page) page));
    +
    +	save_checksum = cpage->phdr.pd_checksum;
    +	cpage->phdr.pd_checksum = 0;
    +	checksum = pg_checksum_block(cpage);
    +	cpage->phdr.pd_checksum = save_checksum;
    +
    +	checksum ^= blkno;
    +	return (uint16)((checksum % 65535) + 1);
    +}
    -- 
    2.43.0
    
    
    
    
    
  3. [PATCH 2/2] Benchmark code for postgres checksums

    Andrew Kim <tenistarkim@gmail.com> — 2025-09-11T05:42:20Z

    From: Andrew kim <andrew.kim@intel.com>
    
    ---
     contrib/meson.build                           |  1 +
     contrib/pg_checksum_bench/meson.build         | 23 +++++++++++++
     .../pg_checksum_bench--1.0.sql                |  8 +++++
     contrib/pg_checksum_bench/pg_checksum_bench.c | 34 +++++++++++++++++++
     .../pg_checksum_bench.control                 |  4 +++
     .../sql/pg_checksum_bench.sql                 | 17 ++++++++++
     6 files changed, 87 insertions(+)
     create mode 100644 contrib/pg_checksum_bench/meson.build
     create mode 100644 contrib/pg_checksum_bench/pg_checksum_bench--1.0.sql
     create mode 100644 contrib/pg_checksum_bench/pg_checksum_bench.c
     create mode 100644 contrib/pg_checksum_bench/pg_checksum_bench.control
     create mode 100644 contrib/pg_checksum_bench/sql/pg_checksum_bench.sql
    
    diff --git a/contrib/meson.build b/contrib/meson.build
    index ed30ee7d639..fe5149aadff 100644
    --- a/contrib/meson.build
    +++ b/contrib/meson.build
    @@ -12,6 +12,7 @@ contrib_doc_args = {
       'install_dir': contrib_doc_dir,
     }
     
    +subdir('pg_checksum_bench')
     subdir('amcheck')
     subdir('auth_delay')
     subdir('auto_explain')
    diff --git a/contrib/pg_checksum_bench/meson.build b/contrib/pg_checksum_bench/meson.build
    new file mode 100644
    index 00000000000..32ccd9efa0f
    --- /dev/null
    +++ b/contrib/pg_checksum_bench/meson.build
    @@ -0,0 +1,23 @@
    +# Copyright (c) 2022-2025, PostgreSQL Global Development Group
    +
    +pg_checksum_bench_sources = files(
    +  'pg_checksum_bench.c',
    +)
    +
    +if host_system == 'windows'
    +  pg_checksum_bench_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
    +    '--NAME', 'pg_checksum_bench',
    +    '--FILEDESC', 'pg_checksum_bench',])
    +endif
    +
    +pg_checksum_bench = shared_module('pg_checksum_bench',
    +  pg_checksum_bench_sources,
    +  kwargs: contrib_mod_args,
    +)
    +contrib_targets += pg_checksum_bench
    +
    +install_data(
    +  'pg_checksum_bench--1.0.sql',
    +  'pg_checksum_bench.control',
    +  kwargs: contrib_data_args,
    +)
    diff --git a/contrib/pg_checksum_bench/pg_checksum_bench--1.0.sql b/contrib/pg_checksum_bench/pg_checksum_bench--1.0.sql
    new file mode 100644
    index 00000000000..5f13cbe3c5e
    --- /dev/null
    +++ b/contrib/pg_checksum_bench/pg_checksum_bench--1.0.sql
    @@ -0,0 +1,8 @@
    +/* contrib/pg_checksum_bench/pg_checksum_bench--1.0.sql */
    +
    +-- complain if script is sourced in psql, rather than via CREATE EXTENSION
    +-- \echo Use "CREATE EXTENSION pg_checksum_bench" to load this file. \quit
    +
    +CREATE FUNCTION drive_pg_checksum(page_count int)
    +	RETURNS pg_catalog.void
    +	AS 'MODULE_PATHNAME' LANGUAGE C;
    diff --git a/contrib/pg_checksum_bench/pg_checksum_bench.c b/contrib/pg_checksum_bench/pg_checksum_bench.c
    new file mode 100644
    index 00000000000..f40f335ff59
    --- /dev/null
    +++ b/contrib/pg_checksum_bench/pg_checksum_bench.c
    @@ -0,0 +1,34 @@
    +#include "postgres.h"
    +#include "fmgr.h"
    +#include "storage/checksum_impl.h"
    +
    +#include <stdio.h>
    +#include <assert.h>
    +
    +PG_MODULE_MAGIC;
    +
    +#define REPEATS 1000000
    +
    +PG_FUNCTION_INFO_V1(drive_pg_checksum);
    +Datum
    +drive_pg_checksum(PG_FUNCTION_ARGS)
    +{
    +	int page_count = PG_GETARG_INT32(0);
    +
    +	PGChecksummablePage * pages = palloc(page_count * sizeof(PGChecksummablePage));
    +	srand(0);
    +	for (size_t i = 0; i < page_count * sizeof(PGChecksummablePage); i++){
    +		char * byte_ptr = (char *) pages;
    +		byte_ptr[i] = rand() % 256;
    +	}
    +
    +	for (int i = 0; i < REPEATS; i++){
    +		const PGChecksummablePage * test_page = pages + (i % page_count);
    +		volatile uint32 result = pg_checksum_block(test_page);
    +		(void) result;
    +	}
    +
    +	pfree((void *) pages);
    +
    +	PG_RETURN_VOID();
    +}
    diff --git a/contrib/pg_checksum_bench/pg_checksum_bench.control b/contrib/pg_checksum_bench/pg_checksum_bench.control
    new file mode 100644
    index 00000000000..4a4e2c9363c
    --- /dev/null
    +++ b/contrib/pg_checksum_bench/pg_checksum_bench.control
    @@ -0,0 +1,4 @@
    +comment = 'pg_checksum benchmark'
    +default_version = '1.0'
    +module_pathname = '$libdir/pg_checksum_bench'
    +relocatable = true
    diff --git a/contrib/pg_checksum_bench/sql/pg_checksum_bench.sql b/contrib/pg_checksum_bench/sql/pg_checksum_bench.sql
    new file mode 100644
    index 00000000000..4b347699953
    --- /dev/null
    +++ b/contrib/pg_checksum_bench/sql/pg_checksum_bench.sql
    @@ -0,0 +1,17 @@
    +CREATE EXTENSION pg_checksum_bench;
    +
    +SELECT drive_pg_checksum(-1);
    +
    +\timing on
    +
    +SELECT drive_pg_checksum(1);
    +SELECT drive_pg_checksum(2);
    +SELECT drive_pg_checksum(4);
    +SELECT drive_pg_checksum(8);
    +SELECT drive_pg_checksum(16);
    +SELECT drive_pg_checksum(32);
    +SELECT drive_pg_checksum(64);
    +SELECT drive_pg_checksum(128);
    +SELECT drive_pg_checksum(256);
    +SELECT drive_pg_checksum(512);
    +SELECT drive_pg_checksum(1024);
    -- 
    2.43.0
    
    
    
    
    
  4. Re: Proposal for enabling auto-vectorization for checksum calculations

    John Naylor <johncnaylorls@gmail.com> — 2025-09-24T06:32:47Z

    On Thu, Sep 11, 2025 at 1:55 PM root <tenistarkim@gmail.com> wrote:
    > Thanks for the feedback. This is v5 of the patchset, updated following your comments:
    >
    > - Moved the function pointer definitions out of common headers and
    >   into src/port, consistent with existing practice.
    
    There is no attachment in this thread, so it's not showing up in the
    commitfest entry (which will need to be moved to next open
    commitfest), so it's not getting CI testing:
    
    https://commitfest.postgresql.org/patch/5726/
    
    Note that the whole series must be attached in a single email, or it
    won't get automated testing.
    
    --
    John Naylor
    Amazon Web Services
    
    
    
    
  5. Re: Proposal for enabling auto-vectorization for checksum calculations

    Andrew Kim <tenistarkim@gmail.com> — 2025-09-24T21:50:44Z

    On Tue, Sep 23, 2025 at 11:32 PM John Naylor johncnaylorls@gmail.com wrote:
    
    There is no attachment in this thread, so it's not showing up in the
    commitfest entry (which will need to be moved to next open
    commitfest), so it's not getting CI testing:
    
    https://commitfest.postgresql.org/patch/5726/
    
    Note that the whole series must be attached in a single email, or it
    won't get automated testing.
    
    Thanks, John. I see the issue now — I’ll attach the entire patch
    series in a single email so it shows up properly in the commitfest and
    gets CI coverage.
    
    Please find attached v6 of the patchset, updated per your feedback.
    
    Best regards,
    Andrew Kim
    
    
    On Tue, Sep 23, 2025 at 11:32 PM John Naylor <johncnaylorls@gmail.com> wrote:
    >
    > On Thu, Sep 11, 2025 at 1:55 PM root <tenistarkim@gmail.com> wrote:
    > > Thanks for the feedback. This is v5 of the patchset, updated following your comments:
    > >
    > > - Moved the function pointer definitions out of common headers and
    > >   into src/port, consistent with existing practice.
    >
    > There is no attachment in this thread, so it's not showing up in the
    > commitfest entry (which will need to be moved to next open
    > commitfest), so it's not getting CI testing:
    >
    > https://commitfest.postgresql.org/patch/5726/
    >
    > Note that the whole series must be attached in a single email, or it
    > won't get automated testing.
    >
    > --
    > John Naylor
    > Amazon Web Services
    
  6. Re: Proposal for enabling auto-vectorization for checksum calculations

    John Naylor <johncnaylorls@gmail.com> — 2025-10-02T05:25:59Z

    On Thu, Sep 25, 2025 at 4:50 AM Andrew Kim <tenistarkim@gmail.com> wrote:
    >
    > Thanks, John. I see the issue now — I’ll attach the entire patch
    > series in a single email so it shows up properly in the commitfest and
    > gets CI coverage.
    
    It's still picking up v4, and the archive link doesn't show any
    further replies. Something must have happened with the email
    threading, since you weren't on the thread at first.  Please create an
    account and edit the entry to point to a more recent message ID:
    
    https://commitfest.postgresql.org/patch/5726/
    
    > Please find attached v6 of the patchset, updated per your feedback.
    
    Thanks. (BTW, we discourage top-posting and prefer to cut to size and
    use inline responses)
    
    This is not a complete review, but some architectural thoughts and
    some things I've noticed.
    
    The top of the checksum_impl.h has this:
    
     * This file exists for the benefit of external programs that may wish to
     * check Postgres page checksums.  They can #include this to get the code
     * referenced by storage/checksum.h.  (Note: you may need to redefine
     * Assert() as empty to compile this successfully externally.)
    
    It's going to be a bit tricky to preserve this ability while allowing
    the core server and client programs to dispatch to a specialized
    implementation, but we should at least try. That means keeping
    pg_checksum_block() and pg_checksum_page() where they live now.
    
    I think a good first refactoring patch would be to move
    src/backend/storage/checksum.c (which your patch doesn't even touch)
    to src/port (and src/include/storage/checksum.h to src/include/port)
    and have all callers use that. With that, I imagine only that
    checksum.c file would include checksum_impl.h.
    
    If that poses a problem, let us know -- we may have to further juggle
    things. If that works without issue, we can proceed with the
    specialization. On that, just a few things to note here, although the
    next patch doesn't need to worry about any of this yet:
    
    +    #if defined(__has_attribute) && __has_attribute (target)
    +    __attribute__((target("avx2")))
    +    #endif
    +    static int avx2_test(void)
    +    {
    +      const char buf@<:@sizeof(__m256i)@:>@;
    +      __m256i accum = _mm256_loadu_si256((const __m256i *) buf);
    +   accum = _mm256_add_epi32(accum, accum);
    +      int result = _mm256_extract_epi32(accum, 0);
    +      return (int) result;
    +    }],
    
    If we're just testing if the target works, we can just use an empty
    function, right?
    
    +#define PG_DECLARE_CHECKSUM_ISA(ISANAME) \
    +uint32 \
    +pg_checksum_block_##ISANAME(const PGChecksummablePage *page);
    +
    +#define PG_DEFINE_CHECKSUM_ISA(ISANAME) \
    +pg_attribute_target(#ISANAME) \
    +uint32 pg_checksum_block_##ISANAME(const PGChecksummablePage *page) \
    
    I find this hard to read compared to just using the actual name.
    
    +avx2_available(void)
    +{
    +#if defined (USE_AVX2_WITH_RUNTIME_CHECK) && defined(__x86_64__)
    
    Why guard on __x86_64__?
    
    +PG_DEFINE_CHECKSUM_ISA(default)
    +{
    + uint32 sums[N_SUMS], result = 0;
    + uint32 i, j;
    [...]
    
    +#ifdef USE_AVX2_WITH_RUNTIME_CHECK
    +PG_DEFINE_CHECKSUM_ISA(avx2)
    +{
    + uint32 sums[N_SUMS], result = 0;
    + uint32 i, j;
    [...]
    
    With the single src/port file idea above, these would just do "return
    pg_checksum_block()" (or pg_checksum_page, whichever makes more
    sense).
    
    + if (avx2_available())
    + {
    + /* optional: patch pointer so next call goes directly */
    + pg_checksum_block = pg_checksum_block_avx2;
    + return pg_checksum_block_avx2(page);
    + }
    
    Not sure what your referring to here by "patching" the pointer, but it
    sounds dangerous. Besides, the cost of indirection is basically zero
    for multi-kilobyte inputs, so there is not even any motivation to
    consider doing differently.
    
    --
    John Naylor
    Amazon Web Services
    
    
    
    
  7. Re: Proposal for enabling auto-vectorization for checksum calculations

    Andrew Kim <tenistarkim@gmail.com> — 2025-10-17T07:15:40Z

    Hi John,
    
    Thank you for your detailed and constructive feedback on the checksum
    AVX2 optimization patch.
    I've carefully addressed all of your concerns and am pleased to share
    the updated V6 implementation.
    
    V6 Implementation adds SIMD-optimized checksum calculation using AVX2
    instructions with automatic fallback to portable implementation,
    incorporating all of your recommended improvements:
    
    1. Code Organization
    Consolidated architecture: Moved all checksum logic into a single
    checksum.c file, eliminating the complexity of separate dispatch files
    Simplified build integration: Streamlined both autoconf and meson
    build configurations
    2. Safety & Robustness
    Eliminated dangerous runtime patching: Replaced direct function
    pointer manipulation with safe dispatch through static function
    pointers
    Thread-safe design: All operations are now inherently thread-safe
    without requiring locks or synchronization
    3. Code Readability
    Removed macro complexity: Replaced PG_DECLARE_CHECKSUM_ISA macros with
    explicit, clear function declarations
    PostgreSQL coding compliance: Follows established PostgreSQL
    conventions throughout
    Simplified conditional compilation: Removed redundant __x86_64__
    guards, relying on configure script's platform detection
    4. Compiler Detection & Compatibility
    Preserved robust testing: Maintained the comprehensive avx2_test
    function that validates both __attribute__((target("avx2"))) support
    and AVX2 intrinsics functionality
    Runtime feature detection: Uses __builtin_cpu_supports("avx2") for
    reliable CPU capability detection
    
    Build cleanly across all library variants (static, shared, server)
    Compile without warnings under strict compiler flags
    I believe this V6 implementation fully addresses your concerns while
    delivering the performance benefits of AVX2 optimization.
    
    Please find the V6 patch attached. I welcome any additional feedback
    you may have.
    
    Best regards,
    Andrew Kim
    
    On Wed, Oct 1, 2025 at 10:26 PM John Naylor <johncnaylorls@gmail.com> wrote:
    >
    > On Thu, Sep 25, 2025 at 4:50 AM Andrew Kim <tenistarkim@gmail.com> wrote:
    > >
    > > Thanks, John. I see the issue now — I’ll attach the entire patch
    > > series in a single email so it shows up properly in the commitfest and
    > > gets CI coverage.
    >
    > It's still picking up v4, and the archive link doesn't show any
    > further replies. Something must have happened with the email
    > threading, since you weren't on the thread at first.  Please create an
    > account and edit the entry to point to a more recent message ID:
    >
    > https://commitfest.postgresql.org/patch/5726/
    >
    > > Please find attached v6 of the patchset, updated per your feedback.
    >
    > Thanks. (BTW, we discourage top-posting and prefer to cut to size and
    > use inline responses)
    >
    > This is not a complete review, but some architectural thoughts and
    > some things I've noticed.
    >
    > The top of the checksum_impl.h has this:
    >
    >  * This file exists for the benefit of external programs that may wish to
    >  * check Postgres page checksums.  They can #include this to get the code
    >  * referenced by storage/checksum.h.  (Note: you may need to redefine
    >  * Assert() as empty to compile this successfully externally.)
    >
    > It's going to be a bit tricky to preserve this ability while allowing
    > the core server and client programs to dispatch to a specialized
    > implementation, but we should at least try. That means keeping
    > pg_checksum_block() and pg_checksum_page() where they live now.
    >
    > I think a good first refactoring patch would be to move
    > src/backend/storage/checksum.c (which your patch doesn't even touch)
    > to src/port (and src/include/storage/checksum.h to src/include/port)
    > and have all callers use that. With that, I imagine only that
    > checksum.c file would include checksum_impl.h.
    >
    > If that poses a problem, let us know -- we may have to further juggle
    > things. If that works without issue, we can proceed with the
    > specialization. On that, just a few things to note here, although the
    > next patch doesn't need to worry about any of this yet:
    >
    > +    #if defined(__has_attribute) && __has_attribute (target)
    > +    __attribute__((target("avx2")))
    > +    #endif
    > +    static int avx2_test(void)
    > +    {
    > +      const char buf@<:@sizeof(__m256i)@:>@;
    > +      __m256i accum = _mm256_loadu_si256((const __m256i *) buf);
    > +   accum = _mm256_add_epi32(accum, accum);
    > +      int result = _mm256_extract_epi32(accum, 0);
    > +      return (int) result;
    > +    }],
    >
    > If we're just testing if the target works, we can just use an empty
    > function, right?
    >
    > +#define PG_DECLARE_CHECKSUM_ISA(ISANAME) \
    > +uint32 \
    > +pg_checksum_block_##ISANAME(const PGChecksummablePage *page);
    > +
    > +#define PG_DEFINE_CHECKSUM_ISA(ISANAME) \
    > +pg_attribute_target(#ISANAME) \
    > +uint32 pg_checksum_block_##ISANAME(const PGChecksummablePage *page) \
    >
    > I find this hard to read compared to just using the actual name.
    >
    > +avx2_available(void)
    > +{
    > +#if defined (USE_AVX2_WITH_RUNTIME_CHECK) && defined(__x86_64__)
    >
    > Why guard on __x86_64__?
    >
    > +PG_DEFINE_CHECKSUM_ISA(default)
    > +{
    > + uint32 sums[N_SUMS], result = 0;
    > + uint32 i, j;
    > [...]
    >
    > +#ifdef USE_AVX2_WITH_RUNTIME_CHECK
    > +PG_DEFINE_CHECKSUM_ISA(avx2)
    > +{
    > + uint32 sums[N_SUMS], result = 0;
    > + uint32 i, j;
    > [...]
    >
    > With the single src/port file idea above, these would just do "return
    > pg_checksum_block()" (or pg_checksum_page, whichever makes more
    > sense).
    >
    > + if (avx2_available())
    > + {
    > + /* optional: patch pointer so next call goes directly */
    > + pg_checksum_block = pg_checksum_block_avx2;
    > + return pg_checksum_block_avx2(page);
    > + }
    >
    > Not sure what your referring to here by "patching" the pointer, but it
    > sounds dangerous. Besides, the cost of indirection is basically zero
    > for multi-kilobyte inputs, so there is not even any motivation to
    > consider doing differently.
    >
    > --
    > John Naylor
    > Amazon Web Services
    
  8. Re: Proposal for enabling auto-vectorization for checksum calculations

    Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru> — 2025-10-17T10:53:43Z

    Greetings!
    
    I've also tried to use AVX2 to speedup checksums and I've found your
    approach quite interesting
    
    But I see some issues with v6 patch
    
    1) checksum.c was moved to src/port, but special meson rules are left in 
    src/backend/storage/page/meson.build. As a result, assembly code for 
    moved src/port/checksum.c doesn't use -funroll-loops and 
    -ftree-vectorize (latter isn't probably needed now, due to the nature of 
    the patch). The same is true for src/port/Makefile, there are no 
    instructions to use CFLAGS_UNROLL_LOOPS and CFLAGS_VECTORIZE
    
    2) checksum.c was moved to src/port, but checksum.h and checksum_impl.h 
    are left in src/include/storage. I think they both should be moved to 
    src/include/port, as John Naylor suggested in his review of v5
    
    3) checksum_impl.h now doesn't provide any code, so including it in 
    external programs won't allow checksum calculation. I think that all 
    code should be in checksum_impl.h, and external programs could just 
    define USE_AVX2_WITH_RUNTIME_CHECK (probably using similar checks as we 
    are) to use AVX2 implementation. If not - then they will default to 
    default realisation
    
    4) I don't understand why do we need to check for AVX2 intrinsics if we 
    don't use those in code (at least I don't see them directly)? As in 
    review of v5, couldn't test functions in configure, config/c-compiler.m4 
    and ./meson.build just be {return 0;} or {return 1;}?
    
    5) Why do we need both src/backend/storage/page/checksum.c and 
    src/port/checksum.c?
    
    6)
    > +/* Function declarations for ISA-specific implementations */
    > +uint32 pg_checksum_block_default(const PGChecksummablePage *page);
    > +#ifdef USE_AVX2_WITH_RUNTIME_CHECK
    > +uint32 pg_checksum_block_avx2(const PGChecksummablePage *page);
    > +#endif
    
    What is "ISA-specific implementations" in this comment? Maybe I'm just 
    not familiar with the term? Or is it an artifact from macro 
    implementation?
    
    7) Why remove all comments from code of pg_checksum_block_default? I 
    could understand if you just removed comments from 
    pg_checksum_block_avx2, since it just duplicates code (though I 
    personally would leave all the comments even when duplicating code), but 
    I don't understand removing comments from pg_checksum_block_default
    
    8) It might be a personal taste, but pg_checksum_block_dispatch looks 
    more like "choose" function from src/port/pg_crc32c_sse42_choose.c and 
    alike. "dispatch" from src/include/port/pg_crc32c looks a little 
    different - we don't choose function pointer once there, we choose 
    between inlined computation and calling a function with runtime check. 
    So I'd suggest changing name of pg_checksum_block_dispatch to 
    pg_checksum_block_choose
    
    Other than those, I think the core of this patch is good
    
    Oleg Tselebrovskiy, PostgresPro
    
    
    
    
  9. Re: Proposal for enabling auto-vectorization for checksum calculations

    Andrew Kim <tenistarkim@gmail.com> — 2025-10-18T21:30:21Z

    Hi Oleg,
    
    Thank you very much for the detailed and constructive feedback on v6 patch.
    It was extremely helpful in refining the architecture and ensuring
    compliance with PostgreSQL coding standards.
    
    I have updated the patch to V7, which I believe addresses all of your
    points, including the critical architectural concerns regarding file
    organization and linking.
    
    Key Changes and Feedback Resolution in V7
    
    The architecture is now consolidated in the src/port module.
    1. Compiler Flags (Unroll/Vectorize)Resolved: Compiler flags
    (CFLAGS_UNROLL_LOOPS) are now correctly placed and applied to
    checksum.c in src/port/Makefile and src/port/meson.
    2. Header OrganizationResolved: checksum.h and checksum_impl.h have
    been moved from src/include/storage/ to src/include/port/ for
    consistent module organization.
    3. External Program CompatibilityResolved: checksum_impl.h is now
    fully self-contained. It provides the static inline implementations
    (pg_checksum_block_default, pg_checksum_block_avx2) and all required
    constants, ensuring external tools can calculate checksums without
    linking to the backend library.
    4. Duplicate FilesResolved: The redundant
    src/backend/storage/page/checksum.c file has been removed,
    consolidating all implementation logic into src/port/checksum.c.
    5. Function NamingResolved: The dispatch pattern now uses
    pg_checksum_block_choose, aligning with the established naming
    conventions (e.g., CRC32C module). The implementations use the clear
    names pg_checksum_block_default and pg_checksum_block_avx2.
    7. Documentation/CommentsResolved: Comprehensive documentation,
    including the detailed FNV-1a algorithm comments, has been restored to
    the portable implementation (pg_checksum_block_default).
    
    Best regards,
    Andrew Kim
    
    On Fri, Oct 17, 2025 at 3:53 AM Oleg Tselebrovskiy
    <o.tselebrovskiy@postgrespro.ru> wrote:
    >
    > Greetings!
    >
    > I've also tried to use AVX2 to speedup checksums and I've found your
    > approach quite interesting
    >
    > But I see some issues with v6 patch
    >
    > 1) checksum.c was moved to src/port, but special meson rules are left in
    > src/backend/storage/page/meson.build. As a result, assembly code for
    > moved src/port/checksum.c doesn't use -funroll-loops and
    > -ftree-vectorize (latter isn't probably needed now, due to the nature of
    > the patch). The same is true for src/port/Makefile, there are no
    > instructions to use CFLAGS_UNROLL_LOOPS and CFLAGS_VECTORIZE
    >
    > 2) checksum.c was moved to src/port, but checksum.h and checksum_impl.h
    > are left in src/include/storage. I think they both should be moved to
    > src/include/port, as John Naylor suggested in his review of v5
    >
    > 3) checksum_impl.h now doesn't provide any code, so including it in
    > external programs won't allow checksum calculation. I think that all
    > code should be in checksum_impl.h, and external programs could just
    > define USE_AVX2_WITH_RUNTIME_CHECK (probably using similar checks as we
    > are) to use AVX2 implementation. If not - then they will default to
    > default realisation
    >
    > 4) I don't understand why do we need to check for AVX2 intrinsics if we
    > don't use those in code (at least I don't see them directly)? As in
    > review of v5, couldn't test functions in configure, config/c-compiler.m4
    > and ./meson.build just be {return 0;} or {return 1;}?
    >
    > 5) Why do we need both src/backend/storage/page/checksum.c and
    > src/port/checksum.c?
    >
    > 6)
    > > +/* Function declarations for ISA-specific implementations */
    > > +uint32 pg_checksum_block_default(const PGChecksummablePage *page);
    > > +#ifdef USE_AVX2_WITH_RUNTIME_CHECK
    > > +uint32 pg_checksum_block_avx2(const PGChecksummablePage *page);
    > > +#endif
    >
    > What is "ISA-specific implementations" in this comment? Maybe I'm just
    > not familiar with the term? Or is it an artifact from macro
    > implementation?
    >
    > 7) Why remove all comments from code of pg_checksum_block_default? I
    > could understand if you just removed comments from
    > pg_checksum_block_avx2, since it just duplicates code (though I
    > personally would leave all the comments even when duplicating code), but
    > I don't understand removing comments from pg_checksum_block_default
    >
    > 8) It might be a personal taste, but pg_checksum_block_dispatch looks
    > more like "choose" function from src/port/pg_crc32c_sse42_choose.c and
    > alike. "dispatch" from src/include/port/pg_crc32c looks a little
    > different - we don't choose function pointer once there, we choose
    > between inlined computation and calling a function with runtime check.
    > So I'd suggest changing name of pg_checksum_block_dispatch to
    > pg_checksum_block_choose
    >
    > Other than those, I think the core of this patch is good
    >
    > Oleg Tselebrovskiy, PostgresPro
    
  10. Re: Proposal for enabling auto-vectorization for checksum calculations

    Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru> — 2025-10-20T15:05:12Z

    Thanks for the new patch version!
    
    Another round of review:
    
    1) I think that changes to contrib/pageinspect/rawpage.c should be in 
    the main patch, not in the benchmark patch. Also, without those chages 
    the main patch can't compile using make world-bin
    
    2) I still don't get why you check for working intrinsics in configure, 
    config/c-compiler.m4 and meson.build, if your patch later uses them. 
    I've gotten correct assembly code with this avx2_test function:
         #include <stdint.h>
         #if defined(__has_attribute) && __has_attribute (target)
         __attribute__((target("avx2")))
         static int avx2_test(void)
         {
    		return 0;
         }
         #endif
    Please, check if this works for you and consider using something similar
    
    3) __builtin_cpu_supports doesn't work on Windows at all. We still have 
    to use approach with __get_cpuid
    
    4) Looks like you can safely remove "port/checksum_impl.h" from 
    src/bin/pg_checksums/pg_checksums.c. It probably links with libpgport 
    and/or libpgcommon, so it gets pg_checksum_page from there. Same with 
    src/bin/pg_upgrade/file.c. Maybe those includes are "for clarity" and 
    you don't need to remove them, but pg_checksums and pg_upgrade seem to 
    work without them
    
    5) You don't need #include <string.h> /* for memcpy */ in 
    checksum_impl.h. At the very least, memcpy was used before your patch 
    without string.h
    
    6) Why did you remove Assert(sizeof(PGChecksummablePage) == BLCKSZ)? Is 
    it always false?
    
    7) Is reformatted variable declaration in pg_checksum_block_default_impl 
    really needed? Is there a good reason for it? Or is it auto-formatting 
    programm output?
    
    8) Your patch removes one whitespace in this line - for (i = 0; i < 
    (uint32)(BLCKSZ / (sizeof(uint32) * N_SUMS)); i++)
    If you wish to fix formatting like that - please, do it in a separate 
    patch. If this was done automatically by some formatting tool - please, 
    revert this change
    
    9) Unneeded empty string
         #define FNV_PRIME 16777619
    
         +
          /* Use a union so that this code is valid under strict aliasing */
          typedef union
    
    10) You need one line with just /* at the beginning of the comment, look 
    at other multiline comments in this file
    +	/* For now, AVX2 implementation is identical to default
    +	 * The compiler will auto-vectorize this with proper flags
    +	 * Future versions could use explicit AVX2 intrinsics here
      	 */
    
    11) Function pg_checksum_block_simple isn't used at all.
    
    12) Why do you need those?
    +#ifndef PG_CHECKSUM_EXTERNAL_INTERFACE
    +#define PG_CHECKSUM_EXTERNAL_INTERFACE
    
    13) Object files are added according to alphabetical order, not logical 
    order (src/port/Makefile)
      	pg_popcount_aarch64.o \
      	pg_popcount_avx512.o \
    +	checksum.o \
      	pg_strong_random.o \
      	pgcheckdir.o \
    
    14) I still think that src/port/checksum.c needs to just include 
    src/include/port/checksum_impl.h and have no other logic to keep 
    checksum_impl.h's role as "header with full implementation"
    Now checksum_impl.h doesn't have any mention of pg_checksum_page
    
    15) Assembly for pg_checksum_block_choose now has full code of 
    pg_checksum_block_default. This is probably a result of using inline 
    functions
    Don't know if this is bad, but it is at least strange
    
    Also, some CFBot checks have failed. Two of them with this error/warning
       checksum.c:88:1: error: no previous prototype for ‘pg_checksum_page’ 
    [-Werror=missing-prototypes]
          88 | pg_checksum_page(char *page, BlockNumber blkno)
             | ^~~~~~~~~~~~~~~~
    Please, address those
    
    Oleg Tselebrovskiy, PostgresPro
    
    
    
    
  11. Re: Proposal for enabling auto-vectorization for checksum calculations

    John Naylor <johncnaylorls@gmail.com> — 2025-10-21T03:30:30Z

    On Fri, Oct 17, 2025 at 2:15 PM Andrew Kim <tenistarkim@gmail.com> wrote:
    >
    > Hi John,
    >
    > Thank you for your detailed and constructive feedback on the checksum
    > AVX2 optimization patch.
    > I've carefully addressed all of your concerns and am pleased to share
    > the updated V6 implementation.
    
    Great! I know we're on v7 now, but I'm going to make a request for
    next time you respond to a review: Respond in-line to each point. As I
    mentioned before,
    
    > On Wed, Oct 1, 2025 at 10:26 PM John Naylor <johncnaylorls@gmail.com> wrote:
    > > (BTW, we discourage top-posting and prefer to cut to size and
    > > use inline responses)
    
    Please don't top-post again, as it clutters our archives in addition
    to making it easy to forget things. I'm now going to copy the things
    that were either not addressed or misunderstood:
    
    > > I think a good first refactoring patch would be to move
    > > src/backend/storage/checksum.c (which your patch doesn't even touch)
    > > to src/port (and src/include/storage/checksum.h to src/include/port)
    > > and have all callers use that. With that, I imagine only that
    > > checksum.c file would include checksum_impl.h.
    > >
    > > If that poses a problem, let us know -- we may have to further juggle
    > > things. If that works without issue, we can proceed with the
    > > specialization.
    
    That means the first patch moves things around without adding any
    platform-specific code, and the next patch adds the specialization. I
    think that would be a lot easier to review and test, especially to
    avoid breaking external programs (see below for more on this). A
    committer can always squash things together if it make sense to do so.
    
    > > +    #if defined(__has_attribute) && __has_attribute (target)
    > > +    __attribute__((target("avx2")))
    > > +    #endif
    > > +    static int avx2_test(void)
    > > +    {
    > > +      const char buf@<:@sizeof(__m256i)@:>@;
    > > +      __m256i accum = _mm256_loadu_si256((const __m256i *) buf);
    > > +   accum = _mm256_add_epi32(accum, accum);
    > > +      int result = _mm256_extract_epi32(accum, 0);
    > > +      return (int) result;
    > > +    }],
    > >
    > > If we're just testing if the target works, we can just use an empty
    > > function, right?
    
    Oleg mentioned the same thing later. It's a waste of time for us to
    repeat ourselves. I said you didn't have to worry about it yet,
    because I was hoping to see the refactoring first.
    
    Now, aside from that I looked further into this:
    
    > > The top of the checksum_impl.h has this:
    > >
    > >  * This file exists for the benefit of external programs that may wish to
    > >  * check Postgres page checksums.  They can #include this to get the code
    > >  * referenced by storage/checksum.h.  (Note: you may need to redefine
    > >  * Assert() as empty to compile this successfully externally.)
    > >
    > > It's going to be a bit tricky to preserve this ability while allowing
    > > the core server and client programs to dispatch to a specialized
    > > implementation, but we should at least try. That means keeping
    > > pg_checksum_block() and pg_checksum_page() where they live now.
    
    Looking at commit f04216341dd1, we have at least one example of an
    external program, pg_filedump. If we can keep this working with
    minimal fuss, it should be fine everywhere.
    
    https://github.com/df7cb/pg_filedump/blob/master/pg_filedump.c#L29
    
    ```
    /* checksum_impl.h uses Assert, which doesn't work outside the server */
    #undef Assert
    #define Assert(X)
    
    #include "storage/checksum.h"
    #include "storage/checksum_impl.h"
    ```
    
    Elsewhere they already have to do things like
    
    ```
    #if PG_VERSION_NUM < 110000
        "   Previous Checkpoint Record: Log File (%u) Offset (0x%08x)\n"
    #endif
    ```
    
    ...so it's probably okay if they have to adjust for a new #include
    path, but I want to verify that actually works, and I don't want to
    make it any more invasive than that. As we proceed, I can volunteer to
    do the work to test that pg_filedump still builds fine with small
    changes. Feel free to try building it yourself, but I'm happy to do
    it.
    
    Oleg posted another review recently, so I won't complicate things
    further, but from a brief glance I will suggest for next time not to
    change any comments that haven't been invalidated by the patch.
    
    --
    John Naylor
    Amazon Web Services
    
    
    
    
  12. Re: Proposal for enabling auto-vectorization for checksum calculations

    Andrew Kim <tenistarkim@gmail.com> — 2025-10-24T07:48:45Z

    Hi John,
    
    Thank you for your review on the previous patch versions.
    
    I've carefully addressed your concerns and those raised by Oleg,
    specifically focusing on patch separation and simplification of the
    configure tests. I am submitting the new version (V8) as two distinct
    patches:
    
    V8-0001: Pure refactoring (moving files, updating includes).
    
    V8-0002: Adding the AVX2 feature (detection, dispatch, and optimization).
    
    As requested, I've used in-line responses below to clarify how each
    point was handled.
    
    On Mon, Oct 20, 2025 at 8:30 PM John Naylor <johncnaylorls@gmail.com> wrote:
    >
    > On Fri, Oct 17, 2025 at 2:15 PM Andrew Kim <tenistarkim@gmail.com> wrote:
    > >
    > > Hi John,
    > >
    > > Thank you for your detailed and constructive feedback on the checksum
    > > AVX2 optimization patch.
    > > I've carefully addressed all of your concerns and am pleased to share
    > > the updated V6 implementation.
    >
    > Great! I know we're on v7 now, but I'm going to make a request for
    > next time you respond to a review: Respond in-line to each point. As I
    > mentioned before,
    >
    > > On Wed, Oct 1, 2025 at 10:26 PM John Naylor <johncnaylorls@gmail.com> wrote:
    > > > (BTW, we discourage top-posting and prefer to cut to size and
    > > > use inline responses)
    >
    > Please don't top-post again, as it clutters our archives in addition
    > to making it easy to forget things. I'm now going to copy the things
    > that were either not addressed or misunderstood:
    >
    
    I apologize for the top-posting in the previous response. I've
    switched to the preferred in-line response format for this and all
    future correspondence.
    
    > > > I think a good first refactoring patch would be to move
    > > > src/backend/storage/checksum.c (which your patch doesn't even touch)
    > > > to src/port (and src/include/storage/checksum.h to src/include/port)
    > > > and have all callers use that. With that, I imagine only that
    > > > checksum.c file would include checksum_impl.h.
    > > >
    > > > If that poses a problem, let us know -- we may have to further juggle
    > > > things. If that works without issue, we can proceed with the
    > > > specialization.
    >
    > That means the first patch moves things around without adding any
    > platform-specific code, and the next patch adds the specialization. I
    > think that would be a lot easier to review and test, especially to
    > avoid breaking external programs (see below for more on this). A
    > committer can always squash things together if it make sense to do so.
    >
    
    Patch V8-0001 (Move-checksum-functions...): This is now a pure
    refactoring patch. It simply moves checksum.c and its headers from
    storage/ to port/ and updates the #include paths in all callers
    (rawpage.c, pg_checksums.c, etc.). It contains no AVX2 or ISA-specific
    code.
    
    Patch V8-0002 (Add-AVX2-optimization...): This patch builds upon the
    first, adding all the new AVX2 functionality, detection, and dispatch
    logic.
    
    > > > +    #if defined(__has_attribute) && __has_attribute (target)
    > > > +    __attribute__((target("avx2")))
    > > > +    #endif
    > > > +    static int avx2_test(void)
    > > > +    {
    > > > +      const char buf@<:@sizeof(__m256i)@:>@;
    > > > +      __m256i accum = _mm256_loadu_si256((const __m256i *) buf);
    > > > +   accum = _mm256_add_epi32(accum, accum);
    > > > +      int result = _mm256_extract_epi32(accum, 0);
    > > > +      return (int) result;
    > > > +    }],
    > > >
    > > > If we're just testing if the target works, we can just use an empty
    > > > function, right?
    >
    > Oleg mentioned the same thing later. It's a waste of time for us to
    > repeat ourselves. I said you didn't have to worry about it yet,
    > because I was hoping to see the refactoring first.
    >
    
    I have implemented this simplification in Patch V8-0002. The test in
    config/c-compiler.m4 is now a simple, empty function with only the
    __attribute__((target("avx2"))) to verify compiler support for the
    attribute, as suggested.
    
    > Now, aside from that I looked further into this:
    >
    > > > The top of the checksum_impl.h has this:
    > > >
    > > >  * This file exists for the benefit of external programs that may wish to
    > > >  * check Postgres page checksums.  They can #include this to get the code
    > > >  * referenced by storage/checksum.h.  (Note: you may need to redefine
    > > >  * Assert() as empty to compile this successfully externally.)
    > > >
    > > > It's going to be a bit tricky to preserve this ability while allowing
    > > > the core server and client programs to dispatch to a specialized
    > > > implementation, but we should at least try. That means keeping
    > > > pg_checksum_block() and pg_checksum_page() where they live now.
    >
    > Looking at commit f04216341dd1, we have at least one example of an
    > external program, pg_filedump. If we can keep this working with
    > minimal fuss, it should be fine everywhere.
    
    The v8 patch series preserves external compatibility. External
    programs like pg_filedump will only need to update their include
    paths:
    /* OLD */
    #include "storage/checksum.h"
    #include "storage/checksum_impl.h"
    
    /* NEW */
    #include "port/checksum.h"
    #include "port/checksum_impl.h"
    
    The function signatures (pg_checksum_block, pg_checksum_page) remain
    identical, and checksum_impl.h still contains the complete
    implementation that external programs can include. The runtime
    dispatch only affects internal PostgreSQL usage.
    
    /* OLD */#include "storage/checksum.h"#include
    "storage/checksum_impl.h"/* NEW */  #include "port/checksum.h"#include
    "port/checksum_impl.h"
    
    
    > https://github.com/df7cb/pg_filedump/blob/master/pg_filedump.c#L29
    >
    > ```
    > /* checksum_impl.h uses Assert, which doesn't work outside the server */
    > #undef Assert
    > #define Assert(X)
    >
    > #include "storage/checksum.h"
    > #include "storage/checksum_impl.h"
    > ```
    >
    > Elsewhere they already have to do things like
    >
    > ```
    > #if PG_VERSION_NUM < 110000
    >     "   Previous Checkpoint Record: Log File (%u) Offset (0x%08x)\n"
    > #endif
    > ```
    >
    > ...so it's probably okay if they have to adjust for a new #include
    > path, but I want to verify that actually works, and I don't want to
    > make it any more invasive than that. As we proceed, I can volunteer to
    > do the work to test that pg_filedump still builds fine with small
    > changes. Feel free to try building it yourself, but I'm happy to do
    > it.
    
    I appreciate your offer to test pg_filedump compatibility. The changes
    in v8 should be minimal for external programs - just the include path
    updates. If you're willing to test this, it would be very valuable
    validation.
    
    >
    > Oleg posted another review recently, so I won't complicate things
    > further, but from a brief glance I will suggest for next time not to
    > change any comments that haven't been invalidated by the patch.
    >
    
     In v8, I've been much more conservative about comment changes. I only
    updated comments that were directly invalidated by the code changes
    (like file path references that changed from storage/ to port/). Other
    comments remain untouched unless they were factually incorrect due to
    the refactoring.
    
    > --
    > John Naylor
    > Amazon Web Services
    
  13. Re: Proposal for enabling auto-vectorization for checksum calculations

    Andrew Kim <tenistarkim@gmail.com> — 2025-10-24T08:09:56Z

    Hi Oleg,
    
    Thank you for the detailed review on v7 patch.
    
    On Mon, Oct 20, 2025 at 8:05 AM Oleg Tselebrovskiy
    <o.tselebrovskiy@postgrespro.ru> wrote:
    >
    > Thanks for the new patch version!
    >
    > Another round of review:
    >
    > 1) I think that changes to contrib/pageinspect/rawpage.c should be in
    > the main patch, not in the benchmark patch. Also, without those chages
    > the main patch can't compile using make world-bin
    >
    This is already correctly handled in v8. The
    contrib/pageinspect/rawpage.c change is in the main patch (v8-0001),
    not in the benchmark patch. The include statement was updated from
    #include "storage/checksum.h" to #include "port/checksum.h" in the
    refactoring patch, which is the correct placement.
    
    > 2) I still don't get why you check for working intrinsics in configure,
    > config/c-compiler.m4 and meson.build, if your patch later uses them.
    > I've gotten correct assembly code with this avx2_test function:
    >      #include <stdint.h>
    >      #if defined(__has_attribute) && __has_attribute (target)
    >      __attribute__((target("avx2")))
    >      static int avx2_test(void)
    >      {
    >                 return 0;
    >      }
    >      #endif
    > Please, check if this works for you and consider using something similar
    >
    
    I agree. In v8, I've simplified the configure tests significantly. The
    config/c-compiler.m4 now uses exactly the pattern you suggested:
    
    > 3) __builtin_cpu_supports doesn't work on Windows at all. We still have
    > to use approach with __get_cpuid
    >
    
    Completely fixed in v8. I've removed all usage of
    __builtin_cpu_supports and implemented proper cross-platform CPU
    detection using __get_cpuid (Linux/GCC) and __cpuid (Windows/MSVC)
    with proper preprocessor guards
    
    > 4) Looks like you can safely remove "port/checksum_impl.h" from
    > src/bin/pg_checksums/pg_checksums.c. It probably links with libpgport
    > and/or libpgcommon, so it gets pg_checksum_page from there. Same with
    > src/bin/pg_upgrade/file.c. Maybe those includes are "for clarity" and
    > you don't need to remove them, but pg_checksums and pg_upgrade seem to
    > work without them
    >
    
    In v8-0001, both files now only include "port/checksum.h". The direct
    inclusion of checksum_impl.h has been removed:
    
    src/bin/pg_checksums/pg_checksums.c: Only includes "port/checksum.h"
    src/bin/pg_upgrade/file.c: Only includes "port/checksum.h"
    
    > 5) You don't need #include <string.h> /* for memcpy */ in
    > checksum_impl.h. At the very least, memcpy was used before your patch
    > without string.h
    >
    
     Confirmed there's no explicit #include <string.h> in the v8
    checksum_impl.h. The memcpy usage relies on the standard PostgreSQL
    includes.
    
    > 6) Why did you remove Assert(sizeof(PGChecksummablePage) == BLCKSZ)? Is
    > it always false?
    >
     I didn't remove it - it's still present in both implementations in
    v8. In both pg_checksum_block_default and pg_checksum_block_avx2, you
    can see:
    
    /* ensure that the size is compatible with the algorithm */
    Assert(sizeof(PGChecksummablePage) == BLCKSZ);
    
    > 7) Is reformatted variable declaration in pg_checksum_block_default_impl
    > really needed? Is there a good reason for it? Or is it auto-formatting
    > programm output?
    >
    
    Sorry, that's my mistake, In v8, I've kept the variable declarations
    consistent with PostgreSQL style without unnecessary reformatting. The
    declarations in both functions follow the same pattern as the original
    code.
    
    > 8) Your patch removes one whitespace in this line - for (i = 0; i <
    > (uint32)(BLCKSZ / (sizeof(uint32) * N_SUMS)); i++)
    > If you wish to fix formatting like that - please, do it in a separate
    > patch. If this was done automatically by some formatting tool - please,
    > revert this change
    >
    
    In v8, I've preserved the original formatting. The for loop maintains
    the original spacing: for (i = 0; i < (uint32) (BLCKSZ /
    (sizeof(uint32) * N_SUMS)); i++) with proper space after (uint32).
    
    > 9) Unneeded empty string
    >      #define FNV_PRIME 16777619
    >
    >      +
    >       /* Use a union so that this code is valid under strict aliasing */
    >       typedef union
    >
    
    Fixed, removed unnecessary blank lines in v8.
    
    > 10) You need one line with just /* at the beginning of the comment, look
    > at other multiline comments in this file
    > +       /* For now, AVX2 implementation is identical to default
    > +        * The compiler will auto-vectorize this with proper flags
    > +        * Future versions could use explicit AVX2 intrinsics here
    >          */
    >
    
    Fixed, it's started style with the opening /* on its own line:
    /*
     * AVX2-optimized block checksum algorithm.
     * Same algorithm as default, but compiled with AVX2 target for
    auto-vectorization.
     */
    
    > 11) Function pg_checksum_block_simple isn't used at all.
    >
    
    There's no pg_checksum_block_simple function in v8. The implementation
    only has the necessary functions: pg_checksum_block_default,
    pg_checksum_block_avx2, and pg_checksum_block_choose.
    
    > 12) Why do you need those?
    > +#ifndef PG_CHECKSUM_EXTERNAL_INTERFACE
    > +#define PG_CHECKSUM_EXTERNAL_INTERFACE
    >
    
    These macros are not present in v8. The implementation is cleaner
    without unnecessary preprocessor guards.
    
    > 13) Object files are added according to alphabetical order, not logical
    > order (src/port/Makefile)
    >         pg_popcount_aarch64.o \
    >         pg_popcount_avx512.o \
    > +       checksum.o \
    >         pg_strong_random.o \
    >         pgcheckdir.o \
    >
    
     In v8, checksum.o is correctly placed in alphabetical order in the
    OBJS list in src/port/Makefile:
    
    OBJS = \
        $(LIBOBJS) \
        $(PG_CRC32C_OBJS) \
        bsearch_arg.o \
        checksum.o \
        chklocale.o \
    
    > 14) I still think that src/port/checksum.c needs to just include
    > src/include/port/checksum_impl.h and have no other logic to keep
    > checksum_impl.h's role as "header with full implementation"
    > Now checksum_impl.h doesn't have any mention of pg_checksum_page
    >
    
     The current v8 approach has checksum.c simply include
    checksum_impl.h, which maintains the "header with full implementation"
    pattern you prefer. However, the function pointer mechanism and
    runtime detection logic is in checksum_impl.h, which means
    pg_checksum_page (the external interface) is also defined there. This
    keeps the external interface clean while maintaining the
    implementation details in the header.
    
    > 15) Assembly for pg_checksum_block_choose now has full code of
    > pg_checksum_block_default. This is probably a result of using inline
    > functions
    > Don't know if this is bad, but it is at least strange
    >
    
    I think that is expected behavior with the function pointer approach.
    The compiler inlines the first call, but subsequent calls use the
    cached function pointer, which is the standard PostgreSQL pattern for
    runtime CPU feature detection (see CRC32C implementation).
    
    > Also, some CFBot checks have failed. Two of them with this error/warning
    >    checksum.c:88:1: error: no previous prototype for ‘pg_checksum_page’
    > [-Werror=missing-prototypes]
    >       88 | pg_checksum_page(char *page, BlockNumber blkno)
    >          | ^~~~~~~~~~~~~~~~
    > Please, address those
    >
    
     In v8, pg_checksum_page is declared in src/include/port/checksum.h,
    which is included by checksum.c. This should resolve the missing
    prototype error.
    
    > Oleg Tselebrovskiy, PostgresPro
    
    
    
    
  14. Re: Proposal for enabling auto-vectorization for checksum calculations

    John Naylor <johncnaylorls@gmail.com> — 2025-10-29T02:50:45Z

    On Fri, Oct 24, 2025 at 2:49 PM Andrew Kim <tenistarkim@gmail.com> wrote:
    > The function signatures (pg_checksum_block, pg_checksum_page) remain
    > identical, and checksum_impl.h still contains the complete
    > implementation that external programs can include. The runtime
    > dispatch only affects internal PostgreSQL usage.
    
    I don't quite understand the architecture here -- all
    platform-specific definitions were put in the "checksum_impl.h"
    header. My thinking was that checksum.c would have all that, with thin
    wrappers around the functions included from that header.
    
    --
    John Naylor
    Amazon Web Services
    
    
    
    
  15. Re: Proposal for enabling auto-vectorization for checksum calculations

    Andrew Kim <tenistarkim@gmail.com> — 2025-11-05T23:49:47Z

    Hi John,
    
    Thank you for reviewing and bringing this up regarding checksum architecture.
    
    On Tue, Oct 28, 2025 at 7:50 PM John Naylor <johncnaylorls@gmail.com> wrote:
    >
    > On Fri, Oct 24, 2025 at 2:49 PM Andrew Kim <tenistarkim@gmail.com> wrote:
    > > The function signatures (pg_checksum_block, pg_checksum_page) remain
    > > identical, and checksum_impl.h still contains the complete
    > > implementation that external programs can include. The runtime
    > > dispatch only affects internal PostgreSQL usage.
    >
    > I don't quite understand the architecture here -- all
    > platform-specific definitions were put in the "checksum_impl.h"
    > header. My thinking was that checksum.c would have all that, with thin
    > wrappers around the functions included from that header.
    
    The v9 patch series is attached.
    I've implemented the architecture as you described.
    checksum_impl.h
    -No platform-specific code (removed all AVX2, CPUID, intrinsics)
    -External programs get a clean, portable standalone implementation
    -Uses #ifndef PG_CHECKSUM_INTERNAL guard to prevent conflicts
    
    checksum.c (full implementation for checksum):
    -Includes checksum_impl.h for the basic implementation and common definitions
    -Contains all platform-specific code (AVX2, CPUID detection, runtime dispatch)
    -Implements thin wrapper functions that provide the public interface
    -Uses #define PG_CHECKSUM_INTERNAL before including the header
    
    >
    > --
    > John Naylor
    > Amazon Web Services
    
    
    Thanks
    Andrew
    
  16. Re: Proposal for enabling auto-vectorization for checksum calculations

    John Naylor <johncnaylorls@gmail.com> — 2025-11-14T11:34:37Z

    On Thu, Nov 6, 2025 at 6:50 AM Andrew Kim <tenistarkim@gmail.com> wrote:
    > The v9 patch series is attached.
    
    Thanks! BTW, I've set the commitfest entry to "Needs Review".
    
    I spent some time with the v9-0001 refactoring patch, and I have one
    observation that's worth sharing now:
    
    --- a/src/bin/pg_checksums/pg_checksums.c
    +++ b/src/bin/pg_checksums/pg_checksums.c
    @@ -29,8 +29,7 @@
     #include "getopt_long.h"
     #include "pg_getopt.h"
     #include "storage/bufpage.h"
    -#include "storage/checksum.h"
    -#include "storage/checksum_impl.h"
    +#include "port/checksum.h"
    
    Outside the backend it is no longer required to include the
    implementation header -- it just links and works correctly. That seems
    like a good thing. In fact...
    
    On Tue, Oct 21, 2025 I wrote:
    > Looking at commit f04216341dd1, we have at least one example of an
    > external program, pg_filedump. If we can keep this working with
    > minimal fuss, it should be fine everywhere.
    
    > https://github.com/df7cb/pg_filedump/blob/master/pg_filedump.c#L29
    >
    > ```
    > /* checksum_impl.h uses Assert, which doesn't work outside the server */
    > #undef Assert
    > #define Assert(X)
    >
    > #include "storage/checksum.h"
    > #include "storage/checksum_impl.h"
    > ```
    
    I tried building pg_filedump against the server with just the 0001
    patch and it also builds fine leaving out the implementation:
    
    diff --git a/pg_filedump.c b/pg_filedump.c
    index 606a85b..0268381 100644
    --- a/pg_filedump.c
    +++ b/pg_filedump.c
    @@ -26,12 +26,7 @@
    
     #include <utils/pg_crc.h>
    
    -/*     checksum_impl.h uses Assert, which doesn't work outside the server */
    -#undef Assert
    -#define Assert(X)
    -
    -#include "storage/checksum.h"
    -#include "storage/checksum_impl.h"
    +#include "port/checksum.h"
     #include "decode.h"
     #include <inttypes.h>
    
    I verified that it does in fact break when built against our master
    branch without the impl.h header.
    
    Further, if I replace the above CRC #include to point instead to our
    hardware-specific API in port/pg_crc32c.h, it builds fine after
    adjusting the typedef that it expects, and interprets the control file
    normally:
    
    <pg_control Contents> *********************************************
    
                              CRC: Correct
               pg_control Version: 1800
                  Catalog Version: 202511051
    ...
    
    I'll think more about this.
    
    --
    John Naylor
    Amazon Web Services
    
    
    
    
  17. Re: Proposal for enabling auto-vectorization for checksum calculations

    Andrew Kim <tenistarkim@gmail.com> — 2025-11-18T03:32:01Z

    Hi John,
    
    Thanks for taking the time to review the v9-0001 refactoring patch and
    for setting the CF entry to Needs Review.
    
    
    On Fri, Nov 14, 2025 at 3:34 AM John Naylor <johncnaylorls@gmail.com> wrote:
    >
    > On Thu, Nov 6, 2025 at 6:50 AM Andrew Kim <tenistarkim@gmail.com> wrote:
    > > The v9 patch series is attached.
    >
    > Thanks! BTW, I've set the commitfest entry to "Needs Review".
    >
    > I spent some time with the v9-0001 refactoring patch, and I have one
    > observation that's worth sharing now:
    >
    > --- a/src/bin/pg_checksums/pg_checksums.c
    > +++ b/src/bin/pg_checksums/pg_checksums.c
    > @@ -29,8 +29,7 @@
    >  #include "getopt_long.h"
    >  #include "pg_getopt.h"
    >  #include "storage/bufpage.h"
    > -#include "storage/checksum.h"
    > -#include "storage/checksum_impl.h"
    > +#include "port/checksum.h"
    >
    > Outside the backend it is no longer required to include the
    > implementation header -- it just links and works correctly. That seems
    > like a good thing. In fact...
    >
    > On Tue, Oct 21, 2025 I wrote:
    > > Looking at commit f04216341dd1, we have at least one example of an
    > > external program, pg_filedump. If we can keep this working with
    > > minimal fuss, it should be fine everywhere.
    >
    > > https://github.com/df7cb/pg_filedump/blob/master/pg_filedump.c#L29
    > >
    > > ```
    > > /* checksum_impl.h uses Assert, which doesn't work outside the server */
    > > #undef Assert
    > > #define Assert(X)
    > >
    > > #include "storage/checksum.h"
    > > #include "storage/checksum_impl.h"
    > > ```
    >
    > I tried building pg_filedump against the server with just the 0001
    > patch and it also builds fine leaving out the implementation:
    >
    > diff --git a/pg_filedump.c b/pg_filedump.c
    > index 606a85b..0268381 100644
    > --- a/pg_filedump.c
    > +++ b/pg_filedump.c
    > @@ -26,12 +26,7 @@
    >
    >  #include <utils/pg_crc.h>
    >
    > -/*     checksum_impl.h uses Assert, which doesn't work outside the server */
    > -#undef Assert
    > -#define Assert(X)
    > -
    > -#include "storage/checksum.h"
    > -#include "storage/checksum_impl.h"
    > +#include "port/checksum.h"
    >  #include "decode.h"
    >  #include <inttypes.h>
    >
    > I verified that it does in fact break when built against our master
    > branch without the impl.h header.
    >
    > Further, if I replace the above CRC #include to point instead to our
    > hardware-specific API in port/pg_crc32c.h, it builds fine after
    > adjusting the typedef that it expects, and interprets the control file
    > normally:
    >
    > <pg_control Contents> *********************************************
    >
    >                           CRC: Correct
    >            pg_control Version: 1800
    >               Catalog Version: 202511051
    > ...
    >
    > I'll think more about this.
    >
    
    I've double-checked everything after applying the v9 checksum patches
    and updating pg_filedump accordingly.
    Following your suggestion, I removed the checksum_impl.h include and
    the Assert redefinition, keeping only the port/checksum.h include.
    build compiles cleanly with the new architecture, and pg_filedump
    functions correctly with the AVX2 optimizations.
    If you agree with this approach, I'd like to prepare a patch for
    upstream submission.
    Please feel free to guide me on the proper process for this. Should I
    submit it to the pg_filedump repository, or would you prefer to handle
    the integration as part of the v9 checksum patch series?
    Thanks again for your testing and guidance!
    
    > --
    > John Naylor
    > Amazon Web Services
    
    
    
    
  18. Re: Proposal for enabling auto-vectorization for checksum calculations

    John Naylor <johncnaylorls@gmail.com> — 2025-11-18T04:48:12Z

    On Tue, Nov 18, 2025 at 10:32 AM Andrew Kim <tenistarkim@gmail.com> wrote:
    
    > I've double-checked everything after applying the v9 checksum patches
    > and updating pg_filedump accordingly.
    > Following your suggestion, I removed the checksum_impl.h include and
    > the Assert redefinition, keeping only the port/checksum.h include.
    > build compiles cleanly with the new architecture, and pg_filedump
    > functions correctly with the AVX2 optimizations.
    > If you agree with this approach, I'd like to prepare a patch for
    > upstream submission.
    
    Thanks, but there is no action required now. I mentioned some
    observations, and I'm going to experiment a bit further.
    
    Also, it's way too early to be suggesting changes to other projects,
    since we haven't committed anything yet. Even things committed can
    occasionally be reverted before beta 1 anyway.
    -- 
    John Naylor
    Amazon Web Services
    
    
    
    
  19. Re: Proposal for enabling auto-vectorization for checksum calculations

    Andrew Kim <tenistarkim@gmail.com> — 2025-11-19T01:18:36Z

    On Mon, Nov 17, 2025 at 8:48 PM John Naylor <johncnaylorls@gmail.com> wrote:
    >
    > On Tue, Nov 18, 2025 at 10:32 AM Andrew Kim <tenistarkim@gmail.com> wrote:
    >
    > > I've double-checked everything after applying the v9 checksum patches
    > > and updating pg_filedump accordingly.
    > > Following your suggestion, I removed the checksum_impl.h include and
    > > the Assert redefinition, keeping only the port/checksum.h include.
    > > build compiles cleanly with the new architecture, and pg_filedump
    > > functions correctly with the AVX2 optimizations.
    > > If you agree with this approach, I'd like to prepare a patch for
    > > upstream submission.
    >
    > Thanks, but there is no action required now. I mentioned some
    > observations, and I'm going to experiment a bit further.
    >
    > Also, it's way too early to be suggesting changes to other projects,
    > since we haven't committed anything yet. Even things committed can
    > occasionally be reverted before beta 1 anyway.
    
    It makes sense, I fully understand. I will standby and wait for your
    next update.
    
    -Andrew Kim
    
    > --
    > John Naylor
    > Amazon Web Services
    
    
    
    
  20. Re: Proposal for enabling auto-vectorization for checksum calculations

    John Naylor <johncnaylorls@gmail.com> — 2026-01-11T23:19:18Z

    On Thu, Nov 6, 2025 at 6:50 AM Andrew Kim <tenistarkim@gmail.com> wrote:
    > The v9 patch series is attached.
    
    Sorry for the delay. I found some issues last month and needed to
    consider the tradeoffs.
    
    First, apparently it has gone unnoticed by everyone, myself included,
    that no version has passed Meson CI since v6:
    
    https://cirrus-ci.com/github/postgresql-cfbot/postgresql/cf%2F5726
    
    That's because `ninja -C build -t missingdeps` gives:
    
    Missing dep: src/port/libpgport_shlib_checksum.a.p/checksum.c.o uses
    src/include/utils/errcodes.h (generated by CUSTOM_COMMAND)
    Missing dep: src/port/libpgport_checksum.a.p/checksum.c.o uses
    src/include/utils/errcodes.h (generated by CUSTOM_COMMAND)
    Processed 2561 nodes.
    Error: There are 2 missing dependency paths.
    2 targets had depfile dependencies on 1 distinct generated inputs
    (from 1 rules)  without a non-depfile dep path to the generator.
    There might be build flakiness if any of the targets listed above are
    built alone, or not late enough, in a clean output directory.
    
    In the back of my mind I was worried of consequences of something in
    src/port depending on backend types, but hadn't seen any in my local
    builds. It seems the proximate cause is the removal of this stanza
    with no equivalent replacement:
    
    --- a/src/backend/storage/page/meson.build
    +++ b/src/backend/storage/page/meson.build
    @@ -1,14 +1,5 @@
     # Copyright (c) 2022-2025, PostgreSQL Global Development Group
    
    -checksum_backend_lib = static_library('checksum_backend_lib',
    -  'checksum.c',
    -  dependencies: backend_build_deps,
    -  kwargs: internal_lib_args,
    -  c_args: vectorize_cflags + unroll_loops_cflags,
    -)
    -
    -backend_link_with += checksum_backend_lib
    
    The low-level algorithm doesn't care about database pages, only
    integers, so first I tried to surgically isolate the concepts, but
    that was too messy.
    
    In the attached v10-0003, I went back to something more similar to v6,
    but incorporated Andrew's idea of using PG_CHECKSUM_INTERNAL to allow
    for flexibility. Now pg_filedump compiles without any changes, so
    that's a plus.
    
    > - Provides public interfaces wrapping the basic implementation
    
    > - No code duplication (checksum.c includes checksum_impl.h)
    
    Upthread I mentioned "thin wrappers", but so far I haven't seen it in
    any patch versions, so I don't think this term means the same thing to
    you as it does to me (I saw pretty clear duplication in v9). It then
    occurred to me that with function attribute targets, doing the naive
    thing throws a compiler error IIRC -- namely just have a notional
    function call that then gets inlined and re-targeted. So in v10 I
    separated the body of checksum_block to a semi-private header to
    provide hardware-specific definitions for core code, while also
    maintaining the same one that external code expects.
    
    For this to be commitable, I think (and I think Oleg agrees) that the
    feature detection should go in src/port. Some of us have been thinking
    of refactoring and centralizing the feature detection, and now may be
    a good time to do it. Before going that far, I wanted to see what
    people think of v10.
    
    --
    John Naylor
    Amazon Web Services
    
  21. Re: Proposal for enabling auto-vectorization for checksum calculations

    Andrew Kim <tenistarkim@gmail.com> — 2026-01-13T01:58:07Z

    Hi John,
    Thanks for taking the time to dig into this,
    I really appreciate the detailed analysis, especially catching the
    Meson CI failure, which I had unfortunately missed after v6.
    
    On Sun, Jan 11, 2026 at 3:19 PM John Naylor <johncnaylorls@gmail.com> wrote:
    >
    > On Thu, Nov 6, 2025 at 6:50 AM Andrew Kim <tenistarkim@gmail.com> wrote:
    > > The v9 patch series is attached.
    >
    > Sorry for the delay. I found some issues last month and needed to
    > consider the tradeoffs.
    >
    > First, apparently it has gone unnoticed by everyone, myself included,
    > that no version has passed Meson CI since v6:
    >
    > https://cirrus-ci.com/github/postgresql-cfbot/postgresql/cf%2F5726
    >
    > That's because `ninja -C build -t missingdeps` gives:
    >
    > Missing dep: src/port/libpgport_shlib_checksum.a.p/checksum.c.o uses
    > src/include/utils/errcodes.h (generated by CUSTOM_COMMAND)
    > Missing dep: src/port/libpgport_checksum.a.p/checksum.c.o uses
    > src/include/utils/errcodes.h (generated by CUSTOM_COMMAND)
    > Processed 2561 nodes.
    > Error: There are 2 missing dependency paths.
    > 2 targets had depfile dependencies on 1 distinct generated inputs
    > (from 1 rules)  without a non-depfile dep path to the generator.
    > There might be build flakiness if any of the targets listed above are
    > built alone, or not late enough, in a clean output directory.
    >
    > In the back of my mind I was worried of consequences of something in
    > src/port depending on backend types, but hadn't seen any in my local
    > builds. It seems the proximate cause is the removal of this stanza
    > with no equivalent replacement:
    >
    > --- a/src/backend/storage/page/meson.build
    > +++ b/src/backend/storage/page/meson.build
    > @@ -1,14 +1,5 @@
    >  # Copyright (c) 2022-2025, PostgreSQL Global Development Group
    >
    > -checksum_backend_lib = static_library('checksum_backend_lib',
    > -  'checksum.c',
    > -  dependencies: backend_build_deps,
    > -  kwargs: internal_lib_args,
    > -  c_args: vectorize_cflags + unroll_loops_cflags,
    > -)
    > -
    > -backend_link_with += checksum_backend_lib
    >
    > The low-level algorithm doesn't care about database pages, only
    > integers, so first I tried to surgically isolate the concepts, but
    > that was too messy.
    >
    > In the attached v10-0003, I went back to something more similar to v6,
    > but incorporated Andrew's idea of using PG_CHECKSUM_INTERNAL to allow
    > for flexibility. Now pg_filedump compiles without any changes, so
    > that's a plus.
    >
    > > - Provides public interfaces wrapping the basic implementation
    >
    > > - No code duplication (checksum.c includes checksum_impl.h)
    >
    > Upthread I mentioned "thin wrappers", but so far I haven't seen it in
    > any patch versions, so I don't think this term means the same thing to
    > you as it does to me (I saw pretty clear duplication in v9). It then
    > occurred to me that with function attribute targets, doing the naive
    > thing throws a compiler error IIRC -- namely just have a notional
    > function call that then gets inlined and re-targeted. So in v10 I
    > separated the body of checksum_block to a semi-private header to
    > provide hardware-specific definitions for core code, while also
    > maintaining the same one that external code expects.
    
    I agree that the missing dependency reported by Meson is a real issue,
    not just a theoretical one.
    The removal of the backend-side checksum_backend_lib stanza without an
    equivalent dependency path explains the CI breakage clearly,
    and your diagnosis makes sense, v10-0003 approach,
    splitting the body of checksum_block into a semi-private
    implementation header while preserving the externally visible
    interface,
    that makes sense to me
    
    
    >
    > For this to be commitable, I think (and I think Oleg agrees) that the
    > feature detection should go in src/port. Some of us have been thinking
    > of refactoring and centralizing the feature detection, and now may be
    > a good time to do it. Before going that far, I wanted to see what
    > people think of v10.
    
    I also agree with you (and Oleg) that feature detection really belongs
    in src/port,
    even if that means doing a bit more refactoring up front. As you said,
    this may actually be a good forcing function to finally consolidate
    feature detection in a cleaner way.
    
    I’m supportive of using v10 as the basis for further discussion and iteration,
    cleaning up Meson dependency declarations so generated headers are
    properly ordered,
    refining the PG_CHECKSUM_INTERNAL usage if needed,
    and assisting with any additional refactoring required to keep
    src/port fully backend-agnostic.
    Thanks again for the careful review and for pushing this in a
    direction that’s more robust and committable.
    
    >
    > --
    > John Naylor
    > Amazon Web Services
    
    
    
    
  22. Re: Proposal for enabling auto-vectorization for checksum calculations

    John Naylor <johncnaylorls@gmail.com> — 2026-01-13T05:07:13Z

    On Tue, Jan 13, 2026 at 8:58 AM Andrew Kim <tenistarkim@gmail.com> wrote:
    > The removal of the backend-side checksum_backend_lib stanza without an
    > equivalent dependency path explains the CI breakage clearly,
    > and your diagnosis makes sense, v10-0003 approach,
    > splitting the body of checksum_block into a semi-private
    > implementation header while preserving the externally visible
    > interface,
    > that makes sense to me
    
    Glad to hear it.
    
    > I’m supportive of using v10 as the basis for further discussion and iteration,
    > cleaning up Meson dependency declarations so generated headers are
    > properly ordered,
    > refining the PG_CHECKSUM_INTERNAL usage if needed,
    
    Great!
    
    It sounds like you've found some issues to address? It's not clear.
    
    -- 
    John Naylor
    Amazon Web Services
    
    
    
    
  23. Re: Proposal for enabling auto-vectorization for checksum calculations

    Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru> — 2026-01-15T08:03:59Z

    Can't respond to the original message about v10 of the patch for some
    reason, so I'll respond here.
    
    > So in v10 I separated the body of checksum_block to
    > a semi-private header to provide hardware-specific definitions
    > for core code, while also maintaining the same one that
    > external code expects
    
    I like the usage of a semi-internal header, less code duplication
    is always good
    
    > In the attached v10-0003, I went back to something more similar to v6,
    > but incorporated Andrew's idea of using PG_CHECKSUM_INTERNAL to allow
    > for flexibility. Now pg_filedump compiles without any changes, so
    > that's a plus.
    
    If I understand correctly, with how code is currently,
    external programms can define PG_CHECKSUM_INTERNAL manually,
    but then they won't have access to static functions inside of
    checksum.c, so all you get is a pointer that leads nowhere, correct?
    I'd like to think that speeding up checksum calculation is something
    that some external programms could appreciate.
    
    Is it possible to move pg_checksum_block_fallback,
    pg_checksum_block_avx2, and pg_checksum_choose to checksum_impl.h?
    It would mean moving all the hardware check to the same header as well.
    Doesn't look or sound pretty, but this would allow external programms
    to chose implementation the same way the core does it, but also just
    change nothing and still have fallback code.
    
    > For this to be commitable, I think (and I think Oleg agrees) that the
    > feature detection should go in src/port. Some of us have been thinking
    > of refactoring and centralizing the feature detection, and now may be
    > a good time to do it.
    
    I do agree with that. I thought that we can continue with v10 as-is,
    commit it with hardware checks still in checksum.c and refactor it with
    everything else, but with my proposition above (and even without it)
    it seems that refactoring of hardware checks should come first.
    
    Also, not moving all those checksum files to src/port saves us from
    thinking about problems with meson and current external programs,
    but, I think, that after hardware checks are refactored, we could
    revisit the question of moving checksum[_impl].h/.c to src/port.
    
    All in all, very happy to see progress on this!
    
    Regards,
    Oleg
    
    
    
    
  24. Re: Proposal for enabling auto-vectorization for checksum calculations

    John Naylor <johncnaylorls@gmail.com> — 2026-01-15T10:35:36Z

    On Thu, Jan 15, 2026 at 3:04 PM Oleg Tselebrovskiy
    <o.tselebrovskiy@postgrespro.ru> wrote:
    
    > > So in v10 I separated the body of checksum_block to
    > > a semi-private header to provide hardware-specific definitions
    > > for core code, while also maintaining the same one that
    > > external code expects
    >
    > I like the usage of a semi-internal header, less code duplication
    > is always good
    
    Glad to hear it.
    
    > If I understand correctly, with how code is currently,
    > external programms can define PG_CHECKSUM_INTERNAL manually,
    > but then they won't have access to static functions inside of
    > checksum.c, so all you get is a pointer that leads nowhere, correct?
    
    Sounds right, but I'm not sure why an external program would define
    it, because it's named...drumroll.."internal".
    
    > I'd like to think that speeding up checksum calculation is something
    > that some external programms could appreciate.
    
    External programs are probably doing some one-off task, so I don't see
    a reason to work harder.
    
    > Also, not moving all those checksum files to src/port saves us from
    > thinking about problems with meson and current external programs,
    > but, I think, that after hardware checks are refactored, we could
    > revisit the question of moving checksum[_impl].h/.c to src/port.
    
    Refactoring the hardware checks is not going to make those two
    problems go away, and I don't understand why you want to move anything
    to begin with.
    
    --
    John Naylor
    Amazon Web Services
    
    
    
    
  25. Re: Proposal for enabling auto-vectorization for checksum calculations

    Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru> — 2026-01-16T04:22:10Z

    Thursday, January 15, 2026 17:35 +07, John Naylor <johncnaylorls@gmail.com> wrote:
    
    >External programs are probably doing some one-off task, so I don't see
    >a reason to work harder.
    
    Well, yeah, I agree. I was mostly thinking about some backup tools that
    could use pg_checksum_page. With a quick search I've found only [1], though.
    
    >> Also, not moving all those checksum files to src/port saves us from
    >> thinking about problems with meson and current external programs,
    >> but, I think, that after hardware checks are refactored, we could
    >> revisit the question of moving checksum[_impl].h/.c to src/port.
    >
    >Refactoring the hardware checks is not going to make those two
    >problems go away, and I don't understand why you want to move anything
    >to begin with.
    
    Yeah, moving checksum files to src/port introduces those two problems,
    and I don't think there is any serious upside in doing this. There was some
    discussion about it during v5 and v6, but as of v10, this is not needed.
    
    [1] - https://github.com/ossc-db/pg_rman
    --
    Regards,
    Oleg
  26. Re: Proposal for enabling auto-vectorization for checksum calculations

    John Naylor <johncnaylorls@gmail.com> — 2026-01-21T11:13:02Z

    Attached is v11 to fix headerscheck, per CI.
    
    --
    John Naylor
    Amazon Web Services
    
  27. Re: Proposal for enabling auto-vectorization for checksum calculations

    Andrew Kim <tenistarkim@gmail.com> — 2026-02-09T08:42:06Z

    Hi John, Thanks for v11.
    Adding the headercheck exception for the internal header looks good to me.
    It would be the right call to fix the CI issues.
    The current structure utilizing the semi-private header looks solid to me.
    -Andrew
    
    On Wed, Jan 21, 2026 at 3:13 AM John Naylor <johncnaylorls@gmail.com> wrote:
    >
    > Attached is v11 to fix headerscheck, per CI.
    >
    > --
    > John Naylor
    > Amazon Web Services
    
    
    
    
  28. Re: Proposal for enabling auto-vectorization for checksum calculations

    Andrew Kim <tenistarkim@gmail.com> — 2026-03-16T08:00:06Z

    It looks like your PostgreSQL build on Cirrus CI is failing during the
    Meson configuration phase because it cannot find the libedit
    libraries.
    Should we add these to the pacman installation command in our CI
    scripts, or is there a preferred way to handle terminal library
    dependencies for the Windows Meson builds?
    
    https://cirrus-ci.com/task/4928462311391232
    
    [01:09:47.468] meson.build:1480:20: ERROR: C shared or static library
    'libedit' not found
    
    On Mon, Feb 9, 2026 at 12:42 AM Andrew Kim <tenistarkim@gmail.com> wrote:
    >
    > Hi John, Thanks for v11.
    > Adding the headercheck exception for the internal header looks good to me.
    > It would be the right call to fix the CI issues.
    > The current structure utilizing the semi-private header looks solid to me.
    > -Andrew
    >
    > On Wed, Jan 21, 2026 at 3:13 AM John Naylor <johncnaylorls@gmail.com> wrote:
    > >
    > > Attached is v11 to fix headerscheck, per CI.
    > >
    > > --
    > > John Naylor
    > > Amazon Web Services
    
    
    
    
  29. Re: Proposal for enabling auto-vectorization for checksum calculations

    John Naylor <johncnaylorls@gmail.com> — 2026-03-17T02:23:25Z

    On Mon, Mar 16, 2026 at 3:00 PM Andrew Kim <tenistarkim@gmail.com> wrote:
    >
    > It looks like your PostgreSQL build on Cirrus CI is failing during the
    > Meson configuration phase because it cannot find the libedit
    > libraries.
    > Should we add these to the pacman installation command in our CI
    > scripts, or is there a preferred way to handle terminal library
    > dependencies for the Windows Meson builds?
    
    I'll leave that to the people who maintain it. Sometimes intermittent
    glitches happen. And please don't top-post.
    
    I've attached v12 which is just a rebase over the new centralized
    feature detection. I also have some review:
    
    +# Check if the compiler supports AVX2 target attribute.
    +# This is used for optimized checksum calculations with runtime detection.
    
    It could possibly be used for other things, in which case this will
    get out of date. It's most reliable to grep for the symbol to see
    where something is used.
    
    Also, the first statement is not true:
    
    +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <stdint.h>
    +    #if defined(__has_attribute) && __has_attribute (target)
    +    __attribute__((target("avx2")))
    +    static int avx2_test(void)
    +    {
    +      return 0;
    +    }
    +    #endif],
    
    With these guards, I think any compiler will pass the test, and CI
    does show it passes on MSVC:
    
    [01:09:52.888] Checking if "AVX2 support" links: YES
    
    The consequence is that two functions get built with identical
    non-AVX2 contents. Then at runtime we pick one of them, but it doesn't
    matter which. This needs to test what it says it's testing.
    
    --
    John Naylor
    Amazon Web Services
    
  30. Re: Proposal for enabling auto-vectorization for checksum calculations

    John Naylor <johncnaylorls@gmail.com> — 2026-03-17T02:25:22Z

    On Tue, Mar 17, 2026 at 9:23 AM John Naylor <johncnaylorls@gmail.com> wrote:
    > I've attached v12 which is just a rebase over the new centralized
    > feature detection. I also have some review:
    
    I forgot to mention elsewhere we generated #include-able snippets of
    code with the suffix ".inc.c" so I went with that rather than add
    exception to headerscheck.
    
    -- 
    John Naylor
    Amazon Web Services
    
    
    
    
  31. Re: Proposal for enabling auto-vectorization for checksum calculations

    John Naylor <johncnaylorls@gmail.com> — 2026-03-30T12:01:02Z

    On Tue, Mar 17, 2026 at 9:23 AM John Naylor <johncnaylorls@gmail.com> wrote:
    > I've attached v12 which is just a rebase over the new centralized
    > feature detection. I also have some review:
    
    Andrew Kim let me know he is not available at this time, so since I
    found only minor issues and we're close to feature freeze I took care
    of them myself in the attached v13. I also further updated an outdated
    comment to reflect that some compilers (for the archives: at least gcc
    8.5 and up) can turn a multiplication by a constant into shifts and
    adds (the FNV prime is pretty sparse in one-bits), so it's no longer
    true that vector multiplication is required. That works on SSE2 and
    powerpc, at least.
    
    I don't remember the last time anyone did measurements, so I went
    ahead and did that:
    
    master: 945ms
    32 AVX2: 335ms
    64 AVX2: 220ms
    
    The last one is just to verify an old code comment, and assertion in
    this thread, that the choice of 32 accumulators left some performance
    on the table. (Even if it weren't in diminishing returns territory, we
    wouldn't consider raising this because that changes the computed
    value, but if I'm updating comments anyway, I wanted to check as much
    as convenient.)
    
    I'll repeat building pg_filedump with this and if that goes well I
    plan to push this week unless there are objections.
    
    -- 
    John Naylor
    Amazon Web Services
    
  32. Re: Proposal for enabling auto-vectorization for checksum calculations

    Ants Aasma <ants.aasma@cybertec.at> — 2026-03-30T15:00:59Z

    On Mon, 30 Mar 2026 at 15:01, John Naylor <johncnaylorls@gmail.com> wrote:
    > I don't remember the last time anyone did measurements, so I went
    > ahead and did that:
    >
    > master: 945ms
    > 32 AVX2: 335ms
    > 64 AVX2: 220ms
    
    I'm guessing this is on a recent Intel. Any extra width is helpful on Intel
    as they doubled vpmulld latency from under us after we had settled on this
    algorithm. uops.info shows that the most recent Arrow Lake-P cores bring
    the latency down to 5. B Intels product lineup is so confusing that it's
    hard to tell which products this core ships in. As far as I can tell not in
    any Xeons yet. AMD has had 3 cycle vpmulld since Zen 3.
    
    Out of curiosity I tried some approximate numbers on Zen 5 for differing
    N_SUMS values. Numbers are ns per iteration for 10M iterations.
    
    GCC 15.2 -O3:
    
                  n16     n32     n64    n128    n256
        x86-64  620.1   482.4   493.9   543.1   584.0
     x86-64-v2  188.6   125.5   121.3   183.9   196.6
     x86-64-v3  185.2   101.3    63.2    60.9   101.6
     x86-64-v4  182.9    86.0    53.9    35.4    30.5
        native  178.2    84.7    54.0    34.5    30.9
    
    clang 20.1 -O3:
    
                  n16     n32     n64    n128    n256
        x86-64  611.7   264.0   254.7   283.9   304.0
     x86-64-v2  603.7   134.0   137.9   236.1   165.8
     x86-64-v3  252.1   103.2    61.9   124.0    96.9
     x86-64-v4  223.9   102.1    61.4   101.7    68.9
        native  203.3    91.0    54.5    35.0    40.4
    
    FWIW I think AVX2 (x86-64-v3) is fine. On AMD the speed is close to core to
    fabric bandwidth and Intel has significantly less bandwidth on server chips.
    
    Regards,
    Ants Aasma
    
  33. Re: Proposal for enabling auto-vectorization for checksum calculations

    John Naylor <johncnaylorls@gmail.com> — 2026-03-31T04:09:26Z

    On Mon, Mar 30, 2026 at 10:01 PM Ants Aasma <ants.aasma@cybertec.at> wrote:
    >
    > On Mon, 30 Mar 2026 at 15:01, John Naylor <johncnaylorls@gmail.com> wrote:
    > > I don't remember the last time anyone did measurements, so I went
    > > ahead and did that:
    > >
    > > master: 945ms
    > > 32 AVX2: 335ms
    > > 64 AVX2: 220ms
    >
    > I'm guessing this is on a recent Intel. Any extra width is helpful on Intel as they doubled vpmulld latency from under us after we had settled on this algorithm.
    
    It's actually ancient and due to be replaced soon, but still several
    years after the adoption of this algorithm.
    
    > FWIW I think AVX2 (x86-64-v3) is fine.
    
    Glad to hear it, although the patch doesn't use that build flag, so
    it's not impossible there is some additional difference in the
    compiler's model. Still, given the variation you found, I'll make sure
    the commit message says "several time faster" so it's not specific to
    my hardware.
    
    --
    John Naylor
    Amazon Web Services
    
    
    
    
  34. Re: Proposal for enabling auto-vectorization for checksum calculations

    John Naylor <johncnaylorls@gmail.com> — 2026-04-04T13:25:40Z

    On Mon, Mar 30, 2026 at 7:01 PM John Naylor <johncnaylorls@gmail.com> wrote:
    > I'll repeat building pg_filedump with this and if that goes well I
    > plan to push this week unless there are objections.
    
    Something change in my environment, or something, because I can't
    build pg_filedump anymore, although it hasn't had any recent new
    commits:
    
    pg_config
    /bin/sh: line 1: mkdir: command not found
    
    Looks like something messed with PATH, but I don't think it was me. In
    any case, very little has changed in the patch since I last built
    pg_filedump successfully, so I won't worry yet.
    
    I pushed with a couple cosmetic adjustments:
    
    - Removed no-longer-needed #includes from configure checks
    - Added a comment that we deliberately don't guard on __has_attribute
    - switch things around to use #ifdef instead of #ifndef for clarity
    
    Thanks Andrew, for picking this up again!
    
    --
    John Naylor
    Amazon Web Services
    
    
    
    
  35. Re: Proposal for enabling auto-vectorization for checksum calculations

    Andrew Kim <tenistarkim@gmail.com> — 2026-04-13T08:32:29Z

    On Sat, Apr 4, 2026 at 6:25 AM John Naylor <johncnaylorls@gmail.com> wrote:
    >
    > On Mon, Mar 30, 2026 at 7:01 PM John Naylor <johncnaylorls@gmail.com> wrote:
    > > I'll repeat building pg_filedump with this and if that goes well I
    > > plan to push this week unless there are objections.
    >
    > Something change in my environment, or something, because I can't
    > build pg_filedump anymore, although it hasn't had any recent new
    > commits:
    >
    > pg_config
    > /bin/sh: line 1: mkdir: command not found
    >
    > Looks like something messed with PATH, but I don't think it was me. In
    > any case, very little has changed in the patch since I last built
    > pg_filedump successfully, so I won't worry yet.
    >
    > I pushed with a couple cosmetic adjustments:
    >
    > - Removed no-longer-needed #includes from configure checks
    > - Added a comment that we deliberately don't guard on __has_attribute
    > - switch things around to use #ifdef instead of #ifndef for clarity
    >
    > Thanks Andrew, for picking this up again!
    
    Thank you for taking care of the final adjustments and pushing the
    patch to master.
    Thank you again for your guidance and for steering this through to the
    finish line.
    It was a pleasure collaborating with you on this optimization.
    - Andrew
    
    >
    > --
    > John Naylor
    > Amazon Web Services