Re: Reduce timing overhead of EXPLAIN ANALYZE using rdtsc?

David Geier <geidav.pg@gmail.com>

From: David Geier <geidav.pg@gmail.com>
To: Hannu Krosing <hannuk@google.com>, Robert Haas <robertmhaas@gmail.com>
Cc: Lukas Fittl <lukas@fittl.com>, Andres Freund <andres@anarazel.de>, Pavel Stehule <pavel.stehule@gmail.com>, vignesh C <vignesh21@gmail.com>, Michael Paquier <michael@paquier.xyz>, Ibrar Ahmed <ibrar.ahmad@gmail.com>, Maciek Sakrejda <m.sakrejda@gmail.com>, pgsql-hackers <pgsql-hackers@postgresql.org>
Date: 2025-12-05T07:46:38Z
Lists: pgsql-hackers

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. pg_test_timing: Also test RDTSC[P] timing, report time source, TSC frequency

  2. Allow retrieving x86 TSC frequency/flags from CPUID

  3. instrumentation: Standardize ticks to nanosecond conversion method

  4. instrumentation: Use Time-Stamp Counter on x86-64 to lower overhead

  5. Zero initialize uses of instr_time about to trigger compiler warnings

  6. instr_time: Represent time as an int64 on all platforms

  7. Add 250c8ee07ed to git-blame-ignore-revs

On 04.12.2025 22:21, Hannu Krosing wrote:
> I have not looked at this patch series yet, but when I played around
> with using rdtsc (or actually some gcc/clang construct that compiled
> to rctsc on c86 and into time register reads on Arm and risc-v) then
> any extra step around it had noticeable overhead. I am not sure
> putting some if or function call around rdtsc call is a good idea.

We have that already. INSTR_TIME_SET_CURRENT_FAST() is currently
implemented as:

static inline instr_time
pg_get_ticks_fast(void)
{
#if defined(__x86_64__) && defined(__linux__)
	if (has_rdtsc)
	{
		instr_time	now;

		now.ticks = __rdtsc();
		return now;
	}
#endif

	return pg_clock_gettime();
}

Based on Robert's suggestion I wanted to add a "fast_clock_source" enum
GUC which can have the following values "auto", "rdtsc", "try_rdtsc" and
"off". With that, at least no additional checks are needed and
performance will remain as previously benchmarked in this thread.

Beyond that, the condition will always evaluate to the same result, so
there won't be branch mispredictions. Doing completely without any check
is impossible, except if we were to JIT compile InstrStartNode() and
InstrStopNode(). But that's a much bigger project.

I'll still add unlikely() around the if (has_rdtsc).

Any input regarding the proposed GUC is welcome.

--
David Geier