Skip to content

Commit cee5238

Browse files
committed
pg_test_timing utility, to measure clock monotonicity and timing cost.
Ants Aasma, Greg Smith
1 parent 5b4f346 commit cee5238

File tree

9 files changed

+451
-2
lines changed

9 files changed

+451
-2
lines changed

contrib/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ SUBDIRS = \
3535
pg_standby \
3636
pg_stat_statements \
3737
pg_test_fsync \
38+
pg_test_timing \
3839
pg_trgm \
3940
pg_upgrade \
4041
pg_upgrade_support \

contrib/pg_test_timing/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/pg_test_timing

contrib/pg_test_timing/Makefile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# contrib/pg_test_timing/Makefile
2+
3+
PGFILEDESC = "pg_test_timing - test timing overhead"
4+
PGAPPICON = win32
5+
6+
PROGRAM = pg_test_timing
7+
OBJS = pg_test_timing.o
8+
9+
ifdef USE_PGXS
10+
PG_CONFIG = pg_config
11+
PGXS := $(shell $(PG_CONFIG) --pgxs)
12+
include $(PGXS)
13+
else
14+
subdir = contrib/pg_test_timing
15+
top_builddir = ../..
16+
include $(top_builddir)/src/Makefile.global
17+
include $(top_srcdir)/contrib/contrib-global.mk
18+
endif
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/*
2+
* pg_test_timing.c
3+
* tests overhead of timing calls and their monotonicity: that
4+
* they always move forward
5+
*/
6+
7+
#include "postgres_fe.h"
8+
9+
#include "getopt_long.h"
10+
#include "portability/instr_time.h"
11+
12+
static const char *progname;
13+
14+
static int32 test_duration = 3;
15+
16+
static void handle_args(int argc, char *argv[]);
17+
static void test_timing(int32);
18+
19+
int
20+
main(int argc, char *argv[])
21+
{
22+
progname = get_progname(argv[0]);
23+
24+
handle_args(argc, argv);
25+
26+
test_timing(test_duration);
27+
28+
return 0;
29+
}
30+
31+
static void
32+
handle_args(int argc, char *argv[])
33+
{
34+
static struct option long_options[] = {
35+
{"duration", required_argument, NULL, 'd'},
36+
{NULL, 0, NULL, 0}
37+
};
38+
int option; /* Command line option */
39+
int optindex = 0; /* used by getopt_long */
40+
41+
if (argc > 1)
42+
{
43+
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0 ||
44+
strcmp(argv[1], "-?") == 0)
45+
{
46+
printf("Usage: %s [-d DURATION]\n", progname);
47+
exit(0);
48+
}
49+
if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
50+
{
51+
puts("pg_test_timing (PostgreSQL) " PG_VERSION);
52+
exit(0);
53+
}
54+
}
55+
56+
while ((option = getopt_long(argc, argv, "d:",
57+
long_options, &optindex)) != -1)
58+
{
59+
switch (option)
60+
{
61+
case 'd':
62+
test_duration = atoi(optarg);
63+
break;
64+
65+
default:
66+
fprintf(stderr, "Try \"%s --help\" for more information.\n",
67+
progname);
68+
exit(1);
69+
break;
70+
}
71+
}
72+
73+
if (argc > optind)
74+
{
75+
fprintf(stderr,
76+
"%s: too many command-line arguments (first is \"%s\")\n",
77+
progname, argv[optind]);
78+
fprintf(stderr, "Try \"%s --help\" for more information.\n",
79+
progname);
80+
exit(1);
81+
}
82+
83+
if (test_duration > 0)
84+
{
85+
printf("Testing timing overhead for %d seconds.\n", test_duration);
86+
}
87+
else
88+
{
89+
fprintf(stderr,
90+
"%s: duration must be a positive integer (duration is \"%d\")\n",
91+
progname, test_duration);
92+
fprintf(stderr, "Try \"%s --help\" for more information.\n",
93+
progname);
94+
exit(1);
95+
}
96+
}
97+
98+
static void
99+
test_timing(int32 duration)
100+
{
101+
uint64 total_time;
102+
int64 time_elapsed = 0;
103+
uint64 loop_count = 0;
104+
uint64 prev, cur;
105+
int32 diff, i, bits, found;
106+
107+
instr_time start_time, end_time, temp;
108+
109+
static int64 histogram[32];
110+
111+
total_time = duration > 0 ? duration * 1000000 : 0;
112+
113+
INSTR_TIME_SET_CURRENT(start_time);
114+
cur = INSTR_TIME_GET_MICROSEC(start_time);
115+
116+
while (time_elapsed < total_time)
117+
{
118+
prev = cur;
119+
INSTR_TIME_SET_CURRENT(temp);
120+
cur = INSTR_TIME_GET_MICROSEC(temp);
121+
diff = cur - prev;
122+
123+
if (diff < 0)
124+
{
125+
printf("Detected clock going backwards in time.\n");
126+
printf("Time warp: %d microseconds\n", diff);
127+
exit(1);
128+
}
129+
130+
bits = 0;
131+
while (diff)
132+
{
133+
diff >>= 1;
134+
bits++;
135+
}
136+
histogram[bits]++;
137+
138+
loop_count++;
139+
INSTR_TIME_SUBTRACT(temp, start_time);
140+
time_elapsed = INSTR_TIME_GET_MICROSEC(temp);
141+
}
142+
143+
INSTR_TIME_SET_CURRENT(end_time);
144+
145+
INSTR_TIME_SUBTRACT(end_time, start_time);
146+
147+
printf("Per loop time including overhead: %0.2f nsec\n",
148+
INSTR_TIME_GET_DOUBLE(end_time) * 1e9 / loop_count);
149+
printf("Histogram of timing durations:\n");
150+
printf("%9s: %10s %9s\n", "< usec", "count", "percent");
151+
152+
found = 0;
153+
for (i = 31; i >= 0; i--)
154+
{
155+
if (found || histogram[i])
156+
{
157+
found = 1;
158+
printf("%9ld: %10ld %8.5f%%\n", 1l << i, histogram[i],
159+
(double) histogram[i] * 100 / loop_count);
160+
}
161+
}
162+
}

doc/src/sgml/config.sgml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4294,7 +4294,9 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
42944294
Enables timing of database I/O calls. This parameter is off by
42954295
default, because it will repeatedly query the operating system for
42964296
the current time, which may cause significant overhead on some
4297-
platforms. Only superusers can change this setting.
4297+
platforms. You can use the <xref linkend="pgtesttiming"> tool to
4298+
measure the overhead of timing on your system. Only superusers can
4299+
change this setting.
42984300
</para>
42994301
</listitem>
43004302
</varlistentry>

doc/src/sgml/contrib.sgml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ CREATE EXTENSION <replaceable>module_name</> FROM unpackaged;
121121
&pgstatstatements;
122122
&pgstattuple;
123123
&pgtestfsync;
124+
&pgtesttiming;
124125
&pgtrgm;
125126
&pgupgrade;
126127
&seg;

doc/src/sgml/filelist.sgml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@
129129
<!ENTITY pgstatstatements SYSTEM "pgstatstatements.sgml">
130130
<!ENTITY pgstattuple SYSTEM "pgstattuple.sgml">
131131
<!ENTITY pgtestfsync SYSTEM "pgtestfsync.sgml">
132+
<!ENTITY pgtesttiming SYSTEM "pgtesttiming.sgml">
132133
<!ENTITY pgtrgm SYSTEM "pgtrgm.sgml">
133134
<!ENTITY pgupgrade SYSTEM "pgupgrade.sgml">
134135
<!ENTITY seg SYSTEM "seg.sgml">

doc/src/sgml/perform.sgml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,9 @@ ROLLBACK;
770770
network transmission costs and I/O conversion costs are not included.
771771
Second, the measurement overhead added by <command>EXPLAIN
772772
ANALYZE</command> can be significant, especially on machines with slow
773-
<function>gettimeofday()</> operating-system calls.
773+
<function>gettimeofday()</> operating-system calls. You can use the
774+
<xref linkend="pgtesttiming"> tool to measure the overhead of timing
775+
on your system.
774776
</para>
775777

776778
<para>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy