Skip to content

Commit f164f86

Browse files
author
Commitfest Bot
committed
[CF 5622] v13 - Reduce timing overhead of EXPLAIN ANALYZE using rdtsc
This branch was automatically generated by a robot using patches from an email thread registered at: https://commitfest.postgresql.org/patch/5622 The branch will be overwritten each time a new patch version is posted to the thread, and also periodically to check for bitrot caused by changes on the master branch. Patch(es): https://www.postgresql.org/message-id/3bd5074a-4d7c-4dc9-8c70-afbe3818a4b1@gmail.com Author(s): Andres Freund, Lukas Fittl, David Geier
2 parents 87a350e + f474e0c commit f164f86

File tree

10 files changed

+418
-44
lines changed

10 files changed

+418
-44
lines changed

src/backend/access/heap/vacuumlazy.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3429,8 +3429,8 @@ count_nondeletable_pages(LVRelState *vacrel, bool *lock_waiter_detected)
34293429
INSTR_TIME_SET_CURRENT(currenttime);
34303430
elapsed = currenttime;
34313431
INSTR_TIME_SUBTRACT(elapsed, starttime);
3432-
if ((INSTR_TIME_GET_MICROSEC(elapsed) / 1000)
3433-
>= VACUUM_TRUNCATE_LOCK_CHECK_INTERVAL)
3432+
if (INSTR_TIME_GET_MILLISEC(elapsed) >=
3433+
VACUUM_TRUNCATE_LOCK_CHECK_INTERVAL)
34343434
{
34353435
if (LockHasWaitersRelation(vacrel->rel, AccessExclusiveLock))
34363436
{

src/backend/executor/instrument.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,13 @@ InstrInit(Instrumentation *instr, int instrument_options)
6767
void
6868
InstrStartNode(Instrumentation *instr)
6969
{
70-
if (instr->need_timer &&
71-
!INSTR_TIME_SET_CURRENT_LAZY(instr->starttime))
72-
elog(ERROR, "InstrStartNode called twice in a row");
70+
if (instr->need_timer)
71+
{
72+
if (!INSTR_TIME_IS_ZERO(instr->starttime))
73+
elog(ERROR, "InstrStartNode called twice in a row");
74+
else
75+
INSTR_TIME_SET_CURRENT_FAST(instr->starttime);
76+
}
7377

7478
/* save buffer usage totals at node entry, if needed */
7579
if (instr->need_bufusage)
@@ -95,7 +99,7 @@ InstrStopNode(Instrumentation *instr, double nTuples)
9599
if (INSTR_TIME_IS_ZERO(instr->starttime))
96100
elog(ERROR, "InstrStopNode called without start");
97101

98-
INSTR_TIME_SET_CURRENT(endtime);
102+
INSTR_TIME_SET_CURRENT_FAST(endtime);
99103
INSTR_TIME_ACCUM_DIFF(instr->counter, endtime, instr->starttime);
100104

101105
INSTR_TIME_SET_ZERO(instr->starttime);

src/backend/utils/init/postinit.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,9 @@ InitPostgres(const char *in_dbname, Oid dboid,
806806
/* Initialize portal manager */
807807
EnablePortalManager();
808808

809+
/* initialize high-precision interval timing */
810+
INSTR_TIME_INITIALIZE();
811+
809812
/*
810813
* Load relcache entries for the shared system catalogs. This must create
811814
* at least entries for pg_database and catalogs used for authentication.

src/bin/pg_test_timing/pg_test_timing.c

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ static long long int largest_diff_count;
3030

3131

3232
static void handle_args(int argc, char *argv[]);
33-
static uint64 test_timing(unsigned int duration);
33+
static uint64 test_timing(unsigned int duration, bool fast_timing);
3434
static void output(uint64 loop_count);
3535

3636
int
@@ -43,10 +43,22 @@ main(int argc, char *argv[])
4343

4444
handle_args(argc, argv);
4545

46-
loop_count = test_timing(test_duration);
47-
46+
/*
47+
* First, test default (non-fast) timing code. A clock source for that
48+
* is always available. Hence, we can unconditionally output the result.
49+
*/
50+
loop_count = test_timing(test_duration, false);
4851
output(loop_count);
4952

53+
/*
54+
* Second, test the fast timing code. This clock source is not always
55+
* available. In that case the loop count will be 0 and we don't print.
56+
*/
57+
printf("\n");
58+
loop_count = test_timing(test_duration, true);
59+
if (loop_count > 0)
60+
output(loop_count);
61+
5062
return 0;
5163
}
5264

@@ -78,7 +90,7 @@ handle_args(int argc, char *argv[])
7890
}
7991
}
8092

81-
while ((option = getopt_long(argc, argv, "d:c:",
93+
while ((option = getopt_long(argc, argv, "d:c:f:",
8294
long_options, &optindex)) != -1)
8395
{
8496
switch (option)
@@ -143,23 +155,44 @@ handle_args(int argc, char *argv[])
143155
exit(1);
144156
}
145157

146-
printf(ngettext("Testing timing overhead for %u second.\n",
147-
"Testing timing overhead for %u seconds.\n",
158+
printf(ngettext("Testing timing overhead for %u second.\n\n",
159+
"Testing timing overhead for %u seconds.\n\n",
148160
test_duration),
149161
test_duration);
150162
}
151163

152164
static uint64
153-
test_timing(unsigned int duration)
165+
test_timing(unsigned int duration, bool fast_timing)
154166
{
155167
uint64 total_time;
156168
int64 time_elapsed = 0;
157169
uint64 loop_count = 0;
158-
uint64 prev,
159-
cur;
160170
instr_time start_time,
161171
end_time,
162-
temp;
172+
prev,
173+
cur;
174+
char *time_source = NULL;
175+
bool fast_timing_available = false;
176+
177+
INSTR_TIME_INITIALIZE();
178+
179+
#if !defined(WIN32) && defined(__x86_64__) && defined(__linux__)
180+
if (fast_timing && has_rdtsc)
181+
{
182+
time_source = "RDTSC";
183+
fast_timing_available = true;
184+
}
185+
else if (has_rdtscp)
186+
time_source = "RDTSCP";
187+
else
188+
time_source = PG_INSTR_CLOCK_NAME;
189+
#else
190+
time_source = PG_INSTR_CLOCK_NAME;
191+
#endif
192+
if (fast_timing && !fast_timing_available)
193+
return 0;
194+
195+
printf(_("Time source: %s\n"), time_source);
163196

164197
/*
165198
* Pre-zero the statistics data structures. They're already zero by
@@ -173,18 +206,23 @@ test_timing(unsigned int duration)
173206

174207
total_time = duration > 0 ? duration * INT64CONST(1000000000) : 0;
175208

176-
INSTR_TIME_SET_CURRENT(start_time);
177-
cur = INSTR_TIME_GET_NANOSEC(start_time);
209+
if (fast_timing)
210+
INSTR_TIME_SET_CURRENT_FAST(start_time);
211+
else
212+
INSTR_TIME_SET_CURRENT(start_time);
213+
cur = start_time;
178214

179215
while (time_elapsed < total_time)
180216
{
181217
int32 diff,
182218
bits;
183219

184220
prev = cur;
185-
INSTR_TIME_SET_CURRENT(temp);
186-
cur = INSTR_TIME_GET_NANOSEC(temp);
187-
diff = cur - prev;
221+
if (fast_timing)
222+
INSTR_TIME_SET_CURRENT_FAST(cur);
223+
else
224+
INSTR_TIME_SET_CURRENT(cur);
225+
diff = INSTR_TIME_DIFF_NANOSEC(cur, prev);
188226

189227
/* Did time go backwards? */
190228
if (unlikely(diff < 0))
@@ -217,11 +255,13 @@ test_timing(unsigned int duration)
217255
largest_diff_count++;
218256

219257
loop_count++;
220-
INSTR_TIME_SUBTRACT(temp, start_time);
221-
time_elapsed = INSTR_TIME_GET_NANOSEC(temp);
258+
time_elapsed = INSTR_TIME_DIFF_NANOSEC(cur, start_time);
222259
}
223260

224-
INSTR_TIME_SET_CURRENT(end_time);
261+
if (fast_timing)
262+
INSTR_TIME_SET_CURRENT_FAST(end_time);
263+
else
264+
INSTR_TIME_SET_CURRENT(end_time);
225265

226266
INSTR_TIME_SUBTRACT(end_time, start_time);
227267

src/bin/pgbench/pgbench.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7334,6 +7334,9 @@ main(int argc, char **argv)
73347334
initRandomState(&state[i].cs_func_rs);
73357335
}
73367336

7337+
/* initialize high-precision interval timing */
7338+
INSTR_TIME_INITIALIZE();
7339+
73377340
/* opening connection... */
73387341
con = doConnect();
73397342
if (con == NULL)

src/bin/psql/startup.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "help.h"
2525
#include "input.h"
2626
#include "mainloop.h"
27+
#include "portability/instr_time.h"
2728
#include "settings.h"
2829

2930
/*
@@ -327,6 +328,9 @@ main(int argc, char *argv[])
327328

328329
PQsetNoticeProcessor(pset.db, NoticeProcessor, NULL);
329330

331+
/* initialize high-precision interval timing */
332+
INSTR_TIME_INITIALIZE();
333+
330334
SyncVariables();
331335

332336
if (options.list_dbs)

src/common/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ OBJS_COMMON = \
5959
file_perm.o \
6060
file_utils.o \
6161
hashfn.o \
62+
instr_time.o \
6263
ip.o \
6364
jsonapi.o \
6465
keywords.o \

0 commit comments

Comments
 (0)