Re: Reduce timing overhead of EXPLAIN ANALYZE using rdtsc?
John Naylor <johncnaylorls@gmail.com>
On Thu, Apr 2, 2026 at 7:54 AM Andres Freund <andres@anarazel.de> wrote:
>
> On 2026-03-25 18:17:44 -0700, Lukas Fittl wrote:
> > From 7cc7e230e05947892b2aa479eba45144beede48e Mon Sep 17 00:00:00 2001
> > From: Lukas Fittl <lukas@fittl.com>
> > Date: Sat, 31 Jan 2026 08:49:46 -0800
> > Subject: [PATCH v14 1/6] Check for HAVE__CPUIDEX and HAVE__GET_CPUID_COUNT
> > separately
>
> John, do you want to take this one, or should I take it?
I can. I took another look just now:
-# Check for __get_cpuid_count() and __cpuidex() in a similar fashion.
+# Check for __get_cpuid_count() and __cpuidex() separately, since we sometimes
+# need __cpuidex() even if __get_cpuid_count() is available.
I'm not sure we need to document here that we need them separately. It
seems more important to do that for the __cpuidex helper that's in a
later patch. I don't feel strongly, though.
I'd probably just do
# Check for __get_cpuid_count()
...
# Check for __cpuidex()
...
Either way, we do need a space between separate tests (ditto Meson).
+if cc.links('''
+ #ifdef _MSC_VER
#include <intrin.h>
+ #else
+ #include <cpuid.h>
+ #endif
int main(int arg, char **argv)
{
- unsigned int exx[4] = {0, 0, 0, 0};
+ int exx[4] = {0, 0, 0, 0};
__cpuidex(exx, 7, 0);
}
Hmm, maybe we can declare unsigned and cast to signed for MSVC as we
do where the code is used.
+# __cpuidex()
+AC_CACHE_CHECK([for __cpuidex], [pgac_cv__cpuidex],
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([#ifdef _MSC_VER
+ #include <intrin.h>
+ #else
+ #include <cpuid.h>
+ #endif],
+ [[int exx[4] = {0, 0, 0, 0};
+ __cpuidex(exx, 7, 0);
+ ]])],
+ [pgac_cv__cpuidex="yes"],
+ [pgac_cv__cpuidex="no"])])
+if test x"$pgac_cv__cpuidex" = x"yes"; then
+ AC_DEFINE(HAVE__CPUIDEX, 1, [Define to 1 if you have __cpuidex.])
fi
MSVC doesn't use autoconf, so we can leave out the intrin.h and keep
using unsigned int.
-#if defined(HAVE__GET_CPUID) || defined(HAVE__GET_CPUID_COUNT)
-#include <cpuid.h>
-#endif
-
-#if defined(HAVE__CPUID) || defined(HAVE__CPUIDEX)
+#if defined(HAVE__CPUID) || defined(HAVE__GET_CPUID) ||
defined(HAVE__GET_CPUID_COUNT) || defined(HAVE__CPUIDEX)
+#if defined(_MSC_VER)
#include <intrin.h>
+#else
+#include <cpuid.h>
+#endif /* defined(_MSC_VER) */
#endif
Now I'm thinking at least one of these will be defined, otherwise we'd
have an #error, so we can just gate solely on _MSC_VER.
--
John Naylor
Amazon Web Services
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