Re: Reduce timing overhead of EXPLAIN ANALYZE using rdtsc?

Andres Freund <andres@anarazel.de>

From: Andres Freund <andres@anarazel.de>
To: Lukas Fittl <lukas@fittl.com>
Cc: John Naylor <johncnaylorls@gmail.com>, Jakub Wartak <jakub.wartak@enterprisedb.com>, Hannu Krosing <hannuk@google.com>, Robert Haas <robertmhaas@gmail.com>, 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>, David Geier <geidav.pg@gmail.com>
Date: 2026-04-07T21:18:53Z
Lists: pgsql-hackers
Hi,

On 2026-04-07 11:24:20 -0700, Lukas Fittl wrote:
> > I've pushed 0001, 0002, 0003.
> 
> Yay! Thank you for pushing :)
> 
> And thank you everyone on this thread for countless reviews, and to
> David for writing some essential parts of this earlier.

Seconded!


> > There's one minor documentation issue in 0004 that I wanted to look at before
> > pushing (and I need to switch to something else for a bit).  The rephrasing
> > gets rid of
> >
> > -   [...] , with the worst case somewhere between 32768 and
> > -   65535 nanoseconds.  In the second block, we can see that typical loop
> > -   time is 16 nanoseconds, and the readings appear to have full nanosecond
> > -   precision.
> >
> > I don't mind loosing the first sentence, but the second one might be useful to
> > somebody?
> 
> Hm, yeah, you're right. What if we word like this:
> 
>   <para>
>    The example results below show system clock timing where 99.99% of loops
>    took between 16 and 63 nanoseconds.  In the second block, we can see that
>    the typical loop time is 40 nanoseconds, and the readings appear to have
>    full nanosecond precision.  Following the system clock results, the
>    <acronym>TSC</acronym> clock source results are shown.  The
>    <command>RDTSCP</command> instruction shows most loops completing in
>    20&ndash;30 nanoseconds, while the <command>RDTSC</command> instruction
>    is the fastest with an average loop time of 20 nanoseconds.  In this
>    example the <acronym>TSC</acronym> clock source will be used by default,
>    but can be disabled by setting <varname>timing_clock_source</varname> to
>    <literal>system</literal>.
>   </para>

Works.

Before pushing I vaccilated a bit about whether to replace the track_io_timing
reference in

+   On platforms that support the <acronym>TSC</acronym> clock source,
+   additional output sections are shown for the <command>RDTSCP</command>
+   instruction (used for general timing needs, such as
+   <varname>track_io_timing</varname>) and the <command>RDTSC</command>
+   instruction (used for <command>EXPLAIN ANALYZE</command>).  At the end

given it's one of the more likely cases to be converted to the fast
timestamping.  But in a decision I may live to regret, I deferred coming up
with a good way to phrase the difference between "per node timing" and
"overall query duration".

Pushed.

Yay!

Took only 6 years :)

Greetings,

Andres Freund



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: Show additional TSC clock source debug info

  2. instrumentation: Avoid CPUID 0x15/0x16 for Hypervisor TSC frequency

  3. pg_test_timing: Also test RDTSC[P] timing, report time source, TSC frequency

  4. Allow retrieving x86 TSC frequency/flags from CPUID

  5. instrumentation: Standardize ticks to nanosecond conversion method

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

  7. Check for __cpuidex and __get_cpuid_count separately

  8. pg_test_timing: Reduce per-loop overhead

  9. Refactor handling of x86 CPUID instructions

  10. instrumentation: Drop INSTR_TIME_SET_CURRENT_LAZY macro

  11. Rename pg_crc32c_sse42_choose.c for general purpose

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

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

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