Skip to content

Commit fc1fba0

Browse files
author
Commitfest Bot
committed
[CF 5726] v8 - Enable auto-vectorization for page checksum calculations
This branch was automatically generated by a robot using patches from an email thread registered at: https://commitfest.postgresql.org/patch/5726 The branch will be overwritten each time a new patch version is posted to the thread, and also periodically to check for bitrot caused by changes on the master branch. Patch(es): https://www.postgresql.org/message-id/CAK64mnejn9AZMYz03e7HX8Uui35PihUuOy=b+iBG=YtRKx0Log@mail.gmail.com Author(s): Matthew Sterrett, Andrew Kim
2 parents 8f29467 + 2cc1593 commit fc1fba0

File tree

24 files changed

+370
-32
lines changed

24 files changed

+370
-32
lines changed

config/c-compiler.m4

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,32 @@ fi
581581
undefine([Ac_cachevar])dnl
582582
])# PGAC_SSE42_CRC32_INTRINSICS
583583

584+
# PGAC_AVX2_SUPPORT
585+
# ---------------------------
586+
# Check if the compiler supports AVX2 target attribute.
587+
# This is used for optimized checksum calculations with runtime detection.
588+
#
589+
# If AVX2 target attribute is supported, sets pgac_avx2_support.
590+
AC_DEFUN([PGAC_AVX2_SUPPORT],
591+
[define([Ac_cachevar], [AS_TR_SH([pgac_cv_avx2_support])])dnl
592+
AC_CACHE_CHECK([for AVX2 target attribute support], [Ac_cachevar],
593+
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <stdint.h>
594+
#if defined(__has_attribute) && __has_attribute (target)
595+
__attribute__((target("avx2")))
596+
static int avx2_test(void)
597+
{
598+
return 0;
599+
}
600+
#endif],
601+
[return avx2_test();])],
602+
[Ac_cachevar=yes],
603+
[Ac_cachevar=no])])
604+
if test x"$Ac_cachevar" = x"yes"; then
605+
pgac_avx2_support=yes
606+
fi
607+
undefine([Ac_cachevar])dnl
608+
])# PGAC_AVX2_SUPPORT
609+
584610
# PGAC_AVX512_PCLMUL_INTRINSICS
585611
# ---------------------------
586612
# Check if the compiler supports AVX-512 carryless multiplication

configure

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17552,6 +17552,58 @@ $as_echo "#define HAVE_XSAVE_INTRINSICS 1" >>confdefs.h
1755217552

1755317553
fi
1755417554

17555+
# Check for AVX2 target and intrinsic support
17556+
#
17557+
if test x"$host_cpu" = x"x86_64"; then
17558+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for AVX2 support" >&5
17559+
$as_echo_n "checking for AVX2 support... " >&6; }
17560+
if ${pgac_cv_avx2_support+:} false; then :
17561+
$as_echo_n "(cached) " >&6
17562+
else
17563+
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
17564+
/* end confdefs.h. */
17565+
#include <immintrin.h>
17566+
#include <stdint.h>
17567+
#if defined(__has_attribute) && __has_attribute (target)
17568+
__attribute__((target("avx2")))
17569+
#endif
17570+
static int avx2_test(void)
17571+
{
17572+
const char buf[sizeof(__m256i)];
17573+
__m256i accum = _mm256_loadu_si256((const __m256i *) buf);
17574+
accum = _mm256_add_epi32(accum, accum);
17575+
int result = _mm256_extract_epi32(accum, 0);
17576+
return (int) result;
17577+
}
17578+
int
17579+
main ()
17580+
{
17581+
return avx2_test();
17582+
;
17583+
return 0;
17584+
}
17585+
_ACEOF
17586+
if ac_fn_c_try_link "$LINENO"; then :
17587+
pgac_cv_avx2_support=yes
17588+
else
17589+
pgac_cv_avx2_support=no
17590+
fi
17591+
rm -f core conftest.err conftest.$ac_objext \
17592+
conftest$ac_exeext conftest.$ac_ext
17593+
fi
17594+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_avx2_support" >&5
17595+
$as_echo "$pgac_cv_avx2_support" >&6; }
17596+
if test x"$pgac_cv_avx2_support" = x"yes"; then
17597+
pgac_avx2_support=yes
17598+
fi
17599+
17600+
if test x"$pgac_avx2_support" = x"yes"; then
17601+
17602+
$as_echo "#define USE_AVX2_WITH_RUNTIME_CHECK 1" >>confdefs.h
17603+
17604+
fi
17605+
fi
17606+
1755517607
# Check for AVX-512 popcount intrinsics
1755617608
#
1755717609
if test x"$host_cpu" = x"x86_64"; then

configure.ac

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2077,6 +2077,15 @@ else
20772077
fi
20782078
fi
20792079

2080+
# Check for AVX2 target and intrinsic support
2081+
#
2082+
if test x"$host_cpu" = x"x86_64"; then
2083+
PGAC_AVX2_SUPPORT()
2084+
if test x"$pgac_avx2_support" = x"yes"; then
2085+
AC_DEFINE(USE_AVX2_WITH_RUNTIME_CHECK, 1, [Define to 1 to use AVX2 instructions with a runtime check.])
2086+
fi
2087+
fi
2088+
20802089
# Check for XSAVE intrinsics
20812090
#
20822091
PGAC_XSAVE_INTRINSICS()

contrib/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ contrib_doc_args = {
1212
'install_dir': contrib_doc_dir,
1313
}
1414

15+
subdir('pg_checksum_bench')
1516
subdir('amcheck')
1617
subdir('auth_delay')
1718
subdir('auto_explain')

contrib/pageinspect/rawpage.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include "miscadmin.h"
2424
#include "pageinspect.h"
2525
#include "storage/bufmgr.h"
26-
#include "storage/checksum.h"
26+
#include "port/checksum.h"
2727
#include "utils/builtins.h"
2828
#include "utils/pg_lsn.h"
2929
#include "utils/rel.h"
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Copyright (c) 2022-2025, PostgreSQL Global Development Group
2+
3+
pg_checksum_bench_sources = files(
4+
'pg_checksum_bench.c',
5+
)
6+
7+
if host_system == 'windows'
8+
pg_checksum_bench_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
9+
'--NAME', 'pg_checksum_bench',
10+
'--FILEDESC', 'pg_checksum_bench',])
11+
endif
12+
13+
pg_checksum_bench = shared_module('pg_checksum_bench',
14+
pg_checksum_bench_sources,
15+
kwargs: contrib_mod_args,
16+
)
17+
contrib_targets += pg_checksum_bench
18+
19+
install_data(
20+
'pg_checksum_bench--1.0.sql',
21+
'pg_checksum_bench.control',
22+
kwargs: contrib_data_args,
23+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/* contrib/pg_checksum_bench/pg_checksum_bench--1.0.sql */
2+
3+
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
4+
-- \echo Use "CREATE EXTENSION pg_checksum_bench" to load this file. \quit
5+
6+
CREATE FUNCTION drive_pg_checksum(page_count int)
7+
RETURNS pg_catalog.void
8+
AS 'MODULE_PATHNAME' LANGUAGE C;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include "postgres.h"
2+
#include "fmgr.h"
3+
#include "port/checksum_impl.h"
4+
5+
#include <stdio.h>
6+
#include <assert.h>
7+
8+
PG_MODULE_MAGIC;
9+
10+
#define REPEATS 1000000
11+
12+
PG_FUNCTION_INFO_V1(drive_pg_checksum);
13+
Datum
14+
drive_pg_checksum(PG_FUNCTION_ARGS)
15+
{
16+
int page_count = PG_GETARG_INT32(0);
17+
18+
PGChecksummablePage * pages = palloc(page_count * sizeof(PGChecksummablePage));
19+
srand(0);
20+
for (size_t i = 0; i < page_count * sizeof(PGChecksummablePage); i++){
21+
char * byte_ptr = (char *) pages;
22+
byte_ptr[i] = rand() % 256;
23+
}
24+
25+
for (int i = 0; i < REPEATS; i++){
26+
const PGChecksummablePage * test_page = pages + (i % page_count);
27+
volatile uint32 result = pg_checksum_block(test_page);
28+
(void) result;
29+
}
30+
31+
pfree((void *) pages);
32+
33+
PG_RETURN_VOID();
34+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
comment = 'pg_checksum benchmark'
2+
default_version = '1.0'
3+
module_pathname = '$libdir/pg_checksum_bench'
4+
relocatable = true
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
CREATE EXTENSION pg_checksum_bench;
2+
3+
SELECT drive_pg_checksum(-1);
4+
5+
\timing on
6+
7+
SELECT drive_pg_checksum(1);
8+
SELECT drive_pg_checksum(2);
9+
SELECT drive_pg_checksum(4);
10+
SELECT drive_pg_checksum(8);
11+
SELECT drive_pg_checksum(16);
12+
SELECT drive_pg_checksum(32);
13+
SELECT drive_pg_checksum(64);
14+
SELECT drive_pg_checksum(128);
15+
SELECT drive_pg_checksum(256);
16+
SELECT drive_pg_checksum(512);
17+
SELECT drive_pg_checksum(1024);

0 commit comments

Comments
 (0)