Re: Reduce timing overhead of EXPLAIN ANALYZE using rdtsc?
David Geier <geidav.pg@gmail.com>
Attachments
- v8-0004-pg_test_timing-Also-test-RDTSC-RDTSCP-timing-and-.patch (text/x-patch) patch v8-0004
- v8-0003-Timing-Use-Time-Stamp-Counter-TSC-on-x86-64-for-f.patch (text/x-patch) patch v8-0003
- v8-0002-Timing-Streamline-ticks-to-nanosecond-conversion-.patch (text/x-patch) patch v8-0002
- v8-0001-Check-for-HAVE__CPUIDEX-and-HAVE__GET_CPUID_COUNT.patch (text/x-patch) patch v8-0001
Hi Lukas, Thanks for taking care of incorporating the latest patch feedback. On 13.02.2026 05:11, Lukas Fittl wrote: > On Thu, Feb 12, 2026 at 4:41 PM Andres Freund <andres@anarazel.de> wrote: >> On 2026-02-12 08:05:27 -0800, Lukas Fittl wrote: > (1) changing the pg_ticks_to_ns logic to have an explicit > "ticks_per_ns_scaled == 0" early check and return at the start, and > setting ticks_per_ns_scaled to 0 when clock_gettime() gets used. This > is similar to what David already suggested in an earlier email. > (2) using uint64 for the ticks_per_ns_scaled/max_ticks_no_overflow > variables - this appears to help GCC generate a bit shift reliably, > instead of an idiv instruction. > > That appears to eliminate the regression in my testing. Attached an > updated v7, which also has some slightly improved commit messages. > > Additional comparisons with the test case you had back at the start of > this thread, with system clock source on my test VM: > > master: > > EXPLAIN (ANALYZE, TIMING ON) SELECT count(*) FROM lotsarows; > Time: 1888.891 ms (best of 3) > pg_test_timing / Average loop time including overhead: 23.53 ns > > v6 (0002 + pg_test_timing prev/cur change): > > EXPLAIN (ANALYZE, TIMING ON) SELECT count(*) FROM lotsarows; > Time: 1897.095 ms (best of 3) > pg_test_timing / Average loop time including overhead: 25.52 ns > > v7 (0002): > > EXPLAIN (ANALYZE, TIMING ON) SELECT count(*) FROM lotsarows; > Time: 1897.148 ms (best of 3) > Average loop time including overhead: 23.14 ns Shouldn't that result be better than master because you optimized the loop overhead in v7-0002? That's at least what I've measured, see test results below. > And when looking at the TSC time source with the full patch set on the same VM: > > v6: > > EXPLAIN (ANALYZE, TIMING ON) SELECT count(*) FROM lotsarows; > Time: 1477.672 ms (best of 3) > pg_test_timing / Average loop time including overhead: 11.79 ns > > v7: > > EXPLAIN (ANALYZE, TIMING ON) SELECT count(*) FROM lotsarows; > Time: 1476.326 ms (best of 3) > pg_test_timing / Average loop time including overhead: 11.78 ns > > Thanks, > Lukas > > [0]: https://godbolt.org/z/EvK1M66n5 > > -- > Lukas Fittl The code wasn't compiling properly on Windows because __x86_64__ is not defined in Visual C++. I've changed the code to use #if defined(__x86_64__) || defined(_M_X64) I've also changed #include <x86intrin.h> to <immintrin.h>. I've tested v8 of the patch (= v7 plus aforementioned changes) on Windows. I'm reporting the best of 3 runs. lotsarows test with parallelism disabled: master: 2781 ms v7: 2776 ms (timing_clock_source = 'system') v7: 2091 ms (timing_clock_source = 'tsc') pg_test_timing: master: 27.04 ns v7: 16.59 ns (QueryxPerformanceCounter) v7: 13.69 ns (RDTSCP) v7: 9.42 ns (RDTSC) v8 of the patch is attached to this mail. -- David Geier
Commits
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
pg_test_timing: Show additional TSC clock source debug info
- 5ba34f6dc838 19 (unreleased) landed
-
instrumentation: Avoid CPUID 0x15/0x16 for Hypervisor TSC frequency
- 7fc36c5db550 19 (unreleased) landed
-
pg_test_timing: Also test RDTSC[P] timing, report time source, TSC frequency
- 16fca4825483 19 (unreleased) landed
-
Allow retrieving x86 TSC frequency/flags from CPUID
- bcb2cf41f964 19 (unreleased) landed
-
instrumentation: Standardize ticks to nanosecond conversion method
- 0022622c93d9 19 (unreleased) landed
-
instrumentation: Use Time-Stamp Counter on x86-64 to lower overhead
- 294520c44487 19 (unreleased) landed
-
Check for __cpuidex and __get_cpuid_count separately
- effaa464afd3 19 (unreleased) landed
-
pg_test_timing: Reduce per-loop overhead
- 82c0cb4e672d 19 (unreleased) landed
-
Refactor handling of x86 CPUID instructions
- be6a7494d2e3 19 (unreleased) landed
-
instrumentation: Drop INSTR_TIME_SET_CURRENT_LAZY macro
- 9d6294c09ed0 19 (unreleased) landed
-
Rename pg_crc32c_sse42_choose.c for general purpose
- b9278871f991 19 (unreleased) cited
-
Zero initialize uses of instr_time about to trigger compiler warnings
- 25b2aba0c3a5 16.0 landed
-
instr_time: Represent time as an int64 on all platforms
- 03023a2664f8 16.0 landed
-
Add 250c8ee07ed to git-blame-ignore-revs
- ff23b592ad66 16.0 cited