Re: Reduce timing overhead of EXPLAIN ANALYZE using rdtsc?
Lukas Fittl <lukas@fittl.com>
On Tue, Mar 3, 2026 at 9:09 AM Andres Freund <andres@anarazel.de> wrote:
> On 2026-03-03 02:29:06 -0800, Lukas Fittl wrote:
> > - Added support for HyperV hypervisor by reading the TSC frequency
> > MSR. This allows Azure Linux VMs to work as well, and in my test gives
> > a similar speed up with RDTSC like reported on AWS. Only annoyance is
> > that to enable it you have to make /dev/cpu/0/msr readable ("setcap
> > cap_sys_rawio=ep" on the binary that accesses it + give the user/group
> > access to the device file)
>
> I rather doubt that giving even just read access to MSRs to unprivileged
> userspace processes is a good idea.
Yeah, that's fair - the interface here is rather crude, and I agree
that MSR access is problematic for non-root.
> But if we read files anyway, wouldn't just using
> /sys/devices/system/cpu/cpu0/cpufreq/base_frequency
> work?
I tested this just now on an Azure VM (Standard D2s v3), and its
close, but unfortunately CPU frequency doesn't match the TSC frequency
(cpuinfo_max_freq is 2800000, scaling_cur_freq is 2496279, and TSC
frequency via MSR is 2793438 -- note that I didn't have base_frequency
on this VM). My understanding is that the TSC clock is virtualized in
HyperV and does not directly match the CPU frequency.
I'm also happy to take this out again - maybe we can get the
HyperV/Azure Linux folks to improve the Kernel side here to pass down
the TSC frequency without needing the MSR, and just not support it for
now.
An alternate idea could be to allow overriding the TSC frequency via a
GUC - then one could use the root user (or a setuid program) to get
the TSC frequency on Azure/HyperV via the MSR and pass it to Postgres
at start. But not sure that's worth the trouble, since it won't help
with environments that don't have a reliable TSC (e.g. Virtualbox, I
think).
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