From 45333e9dabe1e55ccfe8830054b202e4182bb6ef Mon Sep 17 00:00:00 2001 From: John Naylor Date: Sun, 1 Feb 2026 14:41:39 +0700 Subject: [PATCH v7 4/5] Test module for popcount plus bitmapset RDTSC --- src/test/modules/Makefile | 1 + src/test/modules/test_popcount/Makefile | 21 ++++ .../test_popcount/test_popcount--1.0.sql | 3 + .../modules/test_popcount/test_popcount.c | 108 ++++++++++++++++++ .../test_popcount/test_popcount.control | 4 + 5 files changed, 137 insertions(+) create mode 100644 src/test/modules/test_popcount/Makefile create mode 100644 src/test/modules/test_popcount/test_popcount--1.0.sql create mode 100644 src/test/modules/test_popcount/test_popcount.c create mode 100644 src/test/modules/test_popcount/test_popcount.control diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile index 44c7163c1cd..db6bfaec026 100644 --- a/src/test/modules/Makefile +++ b/src/test/modules/Makefile @@ -5,6 +5,7 @@ top_builddir = ../../.. include $(top_builddir)/src/Makefile.global SUBDIRS = \ + test_popcount \ brin \ commit_ts \ delay_execution \ diff --git a/src/test/modules/test_popcount/Makefile b/src/test/modules/test_popcount/Makefile new file mode 100644 index 00000000000..8a49d1ccfc8 --- /dev/null +++ b/src/test/modules/test_popcount/Makefile @@ -0,0 +1,21 @@ +MODULE_big = test_popcount +OBJS = test_popcount.o +PGFILEDESC = "test" +EXTENSION = test_popcount +DATA = test_popcount--1.0.sql + +first: all + +# needed? +test_popcount.o: test_popcount.c + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/test_popcount +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/src/test/modules/test_popcount/test_popcount--1.0.sql b/src/test/modules/test_popcount/test_popcount--1.0.sql new file mode 100644 index 00000000000..51896eb751c --- /dev/null +++ b/src/test/modules/test_popcount/test_popcount--1.0.sql @@ -0,0 +1,3 @@ +CREATE FUNCTION drive_popcount (count int, num int) RETURNS bigint AS 'MODULE_PATHNAME' LANGUAGE C; +CREATE FUNCTION drive_popcount64(count int, num int) RETURNS bigint AS 'MODULE_PATHNAME' LANGUAGE C; +CREATE FUNCTION drive_bms_num_members(count int, num int) RETURNS float8 AS 'MODULE_PATHNAME' LANGUAGE C; diff --git a/src/test/modules/test_popcount/test_popcount.c b/src/test/modules/test_popcount/test_popcount.c new file mode 100644 index 00000000000..5da1ffae188 --- /dev/null +++ b/src/test/modules/test_popcount/test_popcount.c @@ -0,0 +1,108 @@ +/* select drive_popcount(1000000, 1024); */ + +#include + +#include "postgres.h" + +#include "fmgr.h" + +#include "port/pg_bitutils.h" +#include "nodes/bitmapset.h" + +PG_MODULE_MAGIC; + +#ifndef PG_POPCOUNT64 +#define PG_POPCOUNT32(word) pg_popcount32(word) +#define PG_POPCOUNT64(word) pg_popcount64(word) +#endif + + +/* + * drive_popcount64(count int, num int) returns bigint + * + * num is the number of 64-bit words to use + */ +PG_FUNCTION_INFO_V1(drive_popcount64); +Datum +drive_popcount64(PG_FUNCTION_ARGS) +{ + + int count = PG_GETARG_INT32(0); + int num = PG_GETARG_INT32(1); + + int len = num * sizeof(uint64); + uint64 *words = palloc(len); + int64 popcount = 0; + + for (int i = 0; i < num; i++) + words[i] = i; + + while (count--) + { + popcount = 0; + for (int i = 0; i < num; i++) + popcount += PG_POPCOUNT64(words[i]); + } + + PG_RETURN_INT64(popcount); +} + +/* + * drive_popcount(count int, len int) returns bigint + * + * num is the number of 64-bit words to use + */ +PG_FUNCTION_INFO_V1(drive_popcount); +Datum +drive_popcount(PG_FUNCTION_ARGS) +{ + + int count = PG_GETARG_INT32(0); + int num = PG_GETARG_INT32(1); + + int len = num * sizeof(uint64); + uint64 *words = palloc(len); + int64 popcount = 0; + + for (int i = 0; i < num; i++) + words[i] = i; + + while (count--) + popcount = pg_popcount((const char*) words, len); + + PG_RETURN_INT64(popcount); +} + +/* + * drive_bms_num_members(count int, len int) returns bigint + * + * num is the number of bitmap words to use + */ +PG_FUNCTION_INFO_V1(drive_bms_num_members); +Datum +drive_bms_num_members(PG_FUNCTION_ARGS) +{ + + const int count = PG_GETARG_INT32(0); + int countdown = count; + int num = PG_GETARG_INT32(1); + Bitmapset * b; + uint64_t start, finish; + double ticks = 0; + + b = bms_make_singleton(1); + for (int i=0; i < num * BITS_PER_BITMAPWORD; i++) + b = bms_add_member(b, i); + + start = __rdtsc(); + while (countdown--) + { + bms_num_members(b); + } + finish = __rdtsc(); + ticks += finish - start; + + bms_free(b); + + PG_RETURN_FLOAT8(ticks / count); +} diff --git a/src/test/modules/test_popcount/test_popcount.control b/src/test/modules/test_popcount/test_popcount.control new file mode 100644 index 00000000000..6837d724b4d --- /dev/null +++ b/src/test/modules/test_popcount/test_popcount.control @@ -0,0 +1,4 @@ +comment = 'test' +default_version = '1.0' +module_pathname = '$libdir/test_popcount' +relocatable = true -- 2.52.0