public inbox for [email protected]help / color / mirror / Atom feed
[PATCH v2 1/1] resownerbench 46+ messages / 4 participants [nested] [flat]
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH v2 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..e3c0a9710ee --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000 * 10), + (0, 5, 2000000 * 10), + (0, 10, 1000000 * 10), + (0, 60, 100000 * 10), + (0, 70, 100000 * 10), + (0, 100, 100000 * 10), + (0, 1000, 10000 * 10), + (0, 10000, 1000 * 10), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000 * 10), + (9, 100, 100000 * 10), + (9, 1000, 10000 * 10), + (9, 10000, 1000 * 10), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000 * 10), + (65, 100, 100000 * 10), + (65, 1000, 10000 * 10), + (65, 10000, 1000 * 10) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------F30A5443A5D524A5CBC51AE7-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* [PATCH 1/1] resownerbench @ 2020-11-11 22:40 Heikki Linnakangas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Heikki Linnakangas @ 2020-11-11 22:40 UTC (permalink / raw) --- contrib/resownerbench/Makefile | 17 ++ contrib/resownerbench/resownerbench--1.0.sql | 14 ++ contrib/resownerbench/resownerbench.c | 154 +++++++++++++++++++ contrib/resownerbench/resownerbench.control | 6 + contrib/resownerbench/snaptest.sql | 37 +++++ 5 files changed, 228 insertions(+) create mode 100644 contrib/resownerbench/Makefile create mode 100644 contrib/resownerbench/resownerbench--1.0.sql create mode 100644 contrib/resownerbench/resownerbench.c create mode 100644 contrib/resownerbench/resownerbench.control create mode 100644 contrib/resownerbench/snaptest.sql diff --git a/contrib/resownerbench/Makefile b/contrib/resownerbench/Makefile new file mode 100644 index 00000000000..9b0e1cfee1a --- /dev/null +++ b/contrib/resownerbench/Makefile @@ -0,0 +1,17 @@ +MODULE_big = resownerbench +OBJS = resownerbench.o + +EXTENSION = resownerbench +DATA = resownerbench--1.0.sql +PGFILEDESC = "resownerbench - benchmark for ResourceOwners" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/resownerbench +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/resownerbench/resownerbench--1.0.sql b/contrib/resownerbench/resownerbench--1.0.sql new file mode 100644 index 00000000000..d29182f5982 --- /dev/null +++ b/contrib/resownerbench/resownerbench--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/resownerbench/resownerbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION resownerbench" to load this file. \quit + +CREATE FUNCTION snapshotbench_lifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_lifo' +LANGUAGE C STRICT VOLATILE; + +CREATE FUNCTION snapshotbench_fifo(numkeep int, numsnaps int, numiters int) +RETURNS double precision +AS 'MODULE_PATHNAME', 'snapshotbench_fifo' +LANGUAGE C STRICT VOLATILE; diff --git a/contrib/resownerbench/resownerbench.c b/contrib/resownerbench/resownerbench.c new file mode 100644 index 00000000000..acfb6c39199 --- /dev/null +++ b/contrib/resownerbench/resownerbench.c @@ -0,0 +1,154 @@ +#include "postgres.h" + +#include "catalog/pg_type.h" +#include "catalog/pg_statistic.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "libpq/pqsignal.h" +#include "utils/catcache.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/snapmgr.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(snapshotbench_lifo); +PG_FUNCTION_INFO_V1(snapshotbench_fifo); + +/* + * ResourceOwner Performance test, using RegisterSnapshot(). + * + * This takes three parameters: numkeep, numsnaps, numiters. + * + * First, we register 'numkeep' snapshots. They are kept registed + * until the end of the test. Then, we repeatedly register and + * unregister 'numsnaps - numkeep' additional snapshots, repeating + * 'numiters' times. All the register/unregister calls are made in + * LIFO order. + * + * Returns the time spent, in milliseconds. + * + * The idea is to test the performance of ResourceOwnerRemember() + * and ReourceOwnerForget() operations, under different regimes. + * + * In the old implementation, if 'numsnaps' is small enough, all + * the entries fit in the resource owner's small array (it can + * hold 64 entries). + * + * In the new implementation, the array is much smaller, only 8 + * entries, but it's used together with the hash table so that + * we stay in the "array regime" as long as 'numsnaps - numkeep' + * is smaller than 8 entries. + * + * 'numiters' can be adjusted to adjust the overall runtime to be + * suitable long. + */ +Datum +snapshotbench_lifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + while (numregistered > numkeep) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + } + + while (numregistered > 0) + { + numregistered--; + UnregisterSnapshot(rs[numregistered]); + } + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; + + +/* + * Same, but do the register/unregister operations in + * FIFO order. + */ +Datum +snapshotbench_fifo(PG_FUNCTION_ARGS) +{ + int numkeep = PG_GETARG_INT32(0); + int numsnaps = PG_GETARG_INT32(1); + int numiters = PG_GETARG_INT32(2); + int i, + j; + instr_time start, + duration; + Snapshot lsnap; + Snapshot *rs; + int numregistered = 0; + + rs = palloc(Max(numsnaps, numkeep) * sizeof(Snapshot)); + + lsnap = GetLatestSnapshot(); + + PG_SETMASK(&BlockSig); + INSTR_TIME_SET_CURRENT(start); + + while (numregistered < numkeep) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (i = 0 ; i < numiters; i++) + { + while (numregistered < numsnaps) + { + rs[numregistered] = RegisterSnapshot(lsnap); + numregistered++; + } + + for (j = numkeep; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + } + + for (j = 0; j < numregistered; j++) + UnregisterSnapshot(rs[j]); + numregistered = numkeep; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + PG_SETMASK(&UnBlockSig); + + PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(duration)); +}; diff --git a/contrib/resownerbench/resownerbench.control b/contrib/resownerbench/resownerbench.control new file mode 100644 index 00000000000..ada88b8eed8 --- /dev/null +++ b/contrib/resownerbench/resownerbench.control @@ -0,0 +1,6 @@ +# resownerbench + +comment = 'benchmark for ResourceOwners' +default_version = '1.0' +module_pathname = '$libdir/resownerbench' +relocatable = true diff --git a/contrib/resownerbench/snaptest.sql b/contrib/resownerbench/snaptest.sql new file mode 100644 index 00000000000..18c54e13fc9 --- /dev/null +++ b/contrib/resownerbench/snaptest.sql @@ -0,0 +1,37 @@ +-- +-- Performance test RegisterSnapshot/UnregisterSnapshot. +-- +select numkeep, numsnaps, + -- numiters, + -- round(lifo_time_ms) as lifo_total_time_ms, + -- round(fifo_time_ms) as fifo_total_time_ms, + round((lifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as lifo_time_ns, + round((fifo_time_ms::numeric / (numkeep + (numsnaps - numkeep) * numiters)) * 1000000, 1) as fifo_time_ns +from +(values (0, 1, 10000000), + (0, 5, 2000000), + (0, 10, 1000000), + (0, 60, 100000), + (0, 70, 100000), + (0, 100, 100000), + (0, 1000, 10000), + (0, 10000, 1000), + +-- These tests keep 9 snapshots registered across the iterations. That +-- exceeds the size of the little array in the patch, so this exercises +-- the hash lookups. Without the patch, these still fit in the array +-- (it's 64 entries without the patch) + (9, 10, 10000000), + (9, 100, 100000), + (9, 1000, 10000), + (9, 10000, 1000), + +-- These exceed the 64 entry array even without the patch, so these fall +-- in the hash table regime with and without the patch. + (65, 70, 1000000), + (65, 100, 100000), + (65, 1000, 10000), + (65, 10000, 1000) +) AS params (numkeep, numsnaps, numiters), +lateral snapshotbench_lifo(numkeep, numsnaps, numiters) as lifo_time_ms, +lateral snapshotbench_fifo(numkeep, numsnaps, numiters) as fifo_time_ms; -- 2.29.2 --------------1104342304EC6341F5D7C60C-- ^ permalink raw reply [nested|flat] 46+ messages in thread
* Re: request for database identifier in the startup packet @ 2024-05-09 18:20 Dave Cramer <[email protected]> 0 siblings, 1 reply; 46+ messages in thread From: Dave Cramer @ 2024-05-09 18:20 UTC (permalink / raw) To: Robert Haas <[email protected]>; +Cc: PostgreSQL Hackers <[email protected]> Dave Cramer On Thu, 9 May 2024 at 12:22, Robert Haas <[email protected]> wrote: > On Thu, May 9, 2024 at 8:06 AM Dave Cramer <[email protected]> wrote: > > The JDBC driver is currently keeping a per connection cache of types in > the driver. We are seeing cases where the number of columns is quite high. > In one case Prevent fetchFieldMetaData() from being run when unnecessary. · > Issue #3241 · pgjdbc/pgjdbc (github.com) 2.6 Million columns. > > > > If we knew that we were connecting to the same database we could use a > single cache across connections. > > > > I think we would require a server/database identifier in the startup > message. > > I understand the desire to share the cache, but not why that would > require any kind of change to the wire protocol. > > The server identity is actually useful for many things such as knowing which instance of a cluster you are connected to. For the cache however we can't use the IP address to determine which server we are connected to as we could be connected to a pooler. Knowing exactly which server/database makes it relatively easy to have a common cache across connections. Getting that in the startup message seems like a good place Dave ^ permalink raw reply [nested|flat] 46+ messages in thread
* Re: request for database identifier in the startup packet @ 2024-05-09 19:14 Andres Freund <[email protected]> parent: Dave Cramer <[email protected]> 0 siblings, 1 reply; 46+ messages in thread From: Andres Freund @ 2024-05-09 19:14 UTC (permalink / raw) To: Dave Cramer <[email protected]>; +Cc: Robert Haas <[email protected]>; PostgreSQL Hackers <[email protected]> Hi, On 2024-05-09 14:20:49 -0400, Dave Cramer wrote: > On Thu, 9 May 2024 at 12:22, Robert Haas <[email protected]> wrote: > > On Thu, May 9, 2024 at 8:06 AM Dave Cramer <[email protected]> wrote: > > > The JDBC driver is currently keeping a per connection cache of types in > > the driver. We are seeing cases where the number of columns is quite high. > > In one case Prevent fetchFieldMetaData() from being run when unnecessary. · > > Issue #3241 · pgjdbc/pgjdbc (github.com) 2.6 Million columns. > > > > > > If we knew that we were connecting to the same database we could use a > > single cache across connections. > > > > > > I think we would require a server/database identifier in the startup > > message. > > > > I understand the desire to share the cache, but not why that would > > require any kind of change to the wire protocol. > > > > The server identity is actually useful for many things such as knowing > which instance of a cluster you are connected to. > For the cache however we can't use the IP address to determine which server > we are connected to as we could be connected to a pooler. > Knowing exactly which server/database makes it relatively easy to have a > common cache across connections. Getting that in the startup message seems > like a good place ISTM that you could just as well query the information you'd like after connecting. And that's going to be a lot more flexible than having to have precisely the right information in the startup message, and most clients not needing it. Greetings, Andres Freund ^ permalink raw reply [nested|flat] 46+ messages in thread
* Re: request for database identifier in the startup packet @ 2024-05-09 19:19 Robert Haas <[email protected]> parent: Andres Freund <[email protected]> 0 siblings, 1 reply; 46+ messages in thread From: Robert Haas @ 2024-05-09 19:19 UTC (permalink / raw) To: Andres Freund <[email protected]>; +Cc: Dave Cramer <[email protected]>; PostgreSQL Hackers <[email protected]> On Thu, May 9, 2024 at 3:14 PM Andres Freund <[email protected]> wrote: > ISTM that you could just as well query the information you'd like after > connecting. And that's going to be a lot more flexible than having to have > precisely the right information in the startup message, and most clients not > needing it. I agree with this. -- Robert Haas EDB: http://www.enterprisedb.com ^ permalink raw reply [nested|flat] 46+ messages in thread
* Re: request for database identifier in the startup packet @ 2024-05-09 19:33 Dave Cramer <[email protected]> parent: Robert Haas <[email protected]> 0 siblings, 0 replies; 46+ messages in thread From: Dave Cramer @ 2024-05-09 19:33 UTC (permalink / raw) To: Robert Haas <[email protected]>; +Cc: Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]> On Thu, 9 May 2024 at 15:19, Robert Haas <[email protected]> wrote: > On Thu, May 9, 2024 at 3:14 PM Andres Freund <[email protected]> wrote: > > ISTM that you could just as well query the information you'd like after > > connecting. And that's going to be a lot more flexible than having to > have > > precisely the right information in the startup message, and most clients > not > > needing it. > > I agree with this. > > Well other than the extra round trip. Thanks, Dave ^ permalink raw reply [nested|flat] 46+ messages in thread
end of thread, other threads:[~2024-05-09 19:33 UTC | newest] Thread overview: 46+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2020-11-11 22:40 [PATCH v2 1/1] resownerbench Heikki Linnakangas <[email protected]> 2024-05-09 18:20 Re: request for database identifier in the startup packet Dave Cramer <[email protected]> 2024-05-09 19:14 ` Re: request for database identifier in the startup packet Andres Freund <[email protected]> 2024-05-09 19:19 ` Re: request for database identifier in the startup packet Robert Haas <[email protected]> 2024-05-09 19:33 ` Re: request for database identifier in the startup packet Dave Cramer <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox