Re: Reduce timing overhead of EXPLAIN ANALYZE using rdtsc?
Lukas Fittl <lukas@fittl.com>
Attachments
- v24-0001-instrumentation-Show-additional-TSC-clock-source.patch (application/octet-stream) patch v24-0001
On Wed, Apr 8, 2026 at 8:13 AM Andres Freund <andres@anarazel.de> wrote: > > So that's waiting for 100 seconds. > > But the whole test only took 18.88s. So something else than overhead is going > wrong here. > > Oh. > > I think it has a tsc clock source returning bogus results. Look at the > pg_test_timing output. > > > # System clock source: QueryPerformanceCounter > # Average loop time including overhead: 34.54 ns > ... > > # Clock source: RDTSCP > # Average loop time including overhead: 8179723.50 ns > ... > # Fast clock source: RDTSC > # Average loop time including overhead: 4196799.05 ns > ... > > # TSC frequency in use: 7 kHz > # TSC frequency from calibration: 2500044 kHz > # TSC clock source will be used by default, unless timing_clock_source is set to 'system'. > > Sooo, this system claims to have an invariant tsc but the frequency > we are getting from cpuid is completely out of whack. Huh. Yeah, I think this is a case of getting a bad TSC frequency from CPUID. > > Of course that could be for different reasons. It could be that we have a > portability issue around cpuids; we could calculate the frequency incorrectly; > the virtualization technology used might have configured wrong results... > > > I think we might need some sanity checking of the timing results in > pg_test_timing, so that we can pick up this kind of craziness directly in > the tests for pg_test_timing, rather than indirectly like here. > > > We probably should do some basic range checking in the cpuid based frequency > too, clearly 7khz can never be sane. > > But I don't want to add that before we have figured out why we're seeing the > frequency, if it's e.g. that something in the cpuid infrastructure (cpuidex > not working right), or is the vmware logic wrong, ... Agreed. I half wonder if this could be a case of a Hypervisor, but not KVM or VMware, and so we fall through to the regular CPUID information (which AFAIR is different from how Linux itself handles that case, where it'll always do calibration in such cases). I think the solution might be to use the TSC calibration always on other hypervisors. But lets wait for Andrew to confirm the configuration of the machine / have a run with the additional information. > > > Maybe we should add a char **source_details argument to > pg_tsc_calibrate_frequency that pg_test_timing can report? > > I wonder if we also should add a pg_timing_clock_source_info() function that > returns frequency_khz, calibrated_frequency_khz, frequency_source_info or > such? See attached a patch that adds that and shows its output in pg_test_timing. Here is an example from an AWS instance: TSC frequency in use: 2899943 kHz TSC frequency source: x86, hypervisor (kvm), cpuid 0x40000010 TSC frequency from calibration: 2899063 kHz TSC clock source will be used by default, unless timing_clock_source is set to 'system'. And from Azure (HyperV): TSC frequency in use: 2791936 kHz TSC frequency source: x86, calibration TSC frequency from calibration: 2793379 kHz TSC clock source will be used by default, unless timing_clock_source is set to 'system'. Note it doesn't emit the fact that its a hypervisor if calibration was used to keep the code a bit simpler, but would emit it as "hypervisor (other)" or "hypervisor (unknown)" (if cpuidex wasn't available) if cpuid 0x15/0x16 get used. > > > Attached a quick idea how we could rework that to avoid it. > > > > Thoughts? > > Maybe maybe it's worth doing that for 20, but I don't think it's related to > the problem at hand. Ack, agreed this is unrelated to the issue. Thanks, Lukas -- Lukas Fittl
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