Skip to content

tsc: use cpuid 0x16 to get tsc frequency in some cases#3736

Open
sporksmith wants to merge 1 commit intoshadow:mainfrom
sporksmith:cpuid16
Open

tsc: use cpuid 0x16 to get tsc frequency in some cases#3736
sporksmith wants to merge 1 commit intoshadow:mainfrom
sporksmith:cpuid16

Conversation

@sporksmith
Copy link
Copy Markdown
Contributor

Fixes #1519 (hopefully)

@github-actions github-actions bot added Component: Libraries Support functions like LD_PRELOAD and logging Component: Testing Unit and integration tests and frameworks labels Apr 1, 2026
@sporksmith
Copy link
Copy Markdown
Contributor Author

On my machine it doesn't look like cpuid 0x16 would give the right answer, though the comments only note that it's been observed to be correct when the core frequency isn't given in cpuid 0x15, and on my machine it is.

$ ./setup build --debug --test && ./setup test --verbose tsc
...
2: # Start of tsc tests
2: 00:00:00.000042 debug [tsc.c:46] [_frequency_via_cpuid] cpuid 0x15 denominator:2 numerator:156 core:38400000
2: 00:00:00.000045 debug [tsc.c:52] [_frequency_via_cpuid] cpuid 0x16 reports base frequency 184 MHz
2: 00:00:00.000046 debug [tsc.c:128] [_frequency_via_cpuid] Calculated 2995200000 cyclesPerSecond via cpuid 15h
2: 00:00:00.500142 trace [tsc_test.c:64] [closeToNativeRdtsc] Real dt: 0.500089787
2: 00:00:00.500162 trace [tsc_test.c:66] [closeToNativeRdtsc] Real # cycles: 1497867208
2: 00:00:00.500168 trace [tsc_test.c:71] [closeToNativeRdtsc] Emulated # cycles: 1497868930
2: 00:00:00.500172 trace [tsc_test.c:74] [closeToNativeRdtsc] ddcycles: 1722 error:0.000115%
2: ok 1 /tsc/rdtscIsCloseToNative
2: 00:00:00.500252 debug [tsc.c:46] [_frequency_via_cpuid] cpuid 0x15 denominator:2 numerator:156 core:38400000
2: 00:00:00.500259 debug [tsc.c:52] [_frequency_via_cpuid] cpuid 0x16 reports base frequency 184 MHz
2: 00:00:00.500262 debug [tsc.c:128] [_frequency_via_cpuid] Calculated 2995200000 cyclesPerSecond via cpuid 15h
2: 00:00:01.000360 trace [tsc_test.c:64] [closeToNativeRdtsc] Real dt: 0.500089790
2: 00:00:01.000380 trace [tsc_test.c:66] [closeToNativeRdtsc] Real # cycles: 1497867258
2: 00:00:01.000572 trace [tsc_test.c:71] [closeToNativeRdtsc] Emulated # cycles: 1497868939
2: 00:00:01.000583 trace [tsc_test.c:74] [closeToNativeRdtsc] ddcycles: 1681 error:0.000112%
2: ok 2 /tsc/rdtscpIsCloseToNative
2: # End of tsc tests
1/1 Test #2: tsc_test .........................   Passed    1.00 sec

Also unconditionally get and report relevant cpuid info for bug
reporting.

Make more use of `const` since the points of initialization are a
bit separated from points of use.
@sporksmith
Copy link
Copy Markdown
Contributor Author

sporksmith commented Apr 1, 2026

Oops, I'd masked off too many bits of the cpuid 0x16 result. With that fixed I get 3 GHz via the new way, vs 2.99 GHz via the "regular" way. So that seems a bit more promising

2: Test command: /home/jnewsome/projects/shadow/build/src/lib/asm-util/tsc_test
2: Test timeout computed to be: 20
2: # random seed: R02Se38f675d6980ee44d71a4e11e554287b
2: 00:00:00.000001 trace [tsc_test.c:109] [_hostHasInvariantTimer] cpuid 0x80000007 returned edx:100
2: 1..2
2: # Start of tsc tests
2: 00:00:00.000050 trace [tsc.c:43] [_frequency_via_cpuid] rax 657060 -> family_id:0x6 extended_model_id:0xa model:0xa
2: 00:00:00.000054 debug [tsc.c:59] [_frequency_via_cpuid] cpuid 0x15 denominator:2 numerator:156 core:38400000
2: 00:00:00.000057 debug [tsc.c:63] [_frequency_via_cpuid] cpuid 0x16 reports base frequency 3000 MHz
2: 00:00:00.000059 debug [tsc.c:126] [_frequency_via_cpuid] Calculated 2995200000 cyclesPerSecond via cpuid 15h
2: 00:00:00.500374 trace [tsc_test.c:64] [closeToNativeRdtsc] Real dt: 0.500309255
2: 00:00:00.500399 trace [tsc_test.c:66] [closeToNativeRdtsc] Real # cycles: 1498525918
2: 00:00:00.500403 trace [tsc_test.c:71] [closeToNativeRdtsc] Emulated # cycles: 1498526280
2: 00:00:00.500406 trace [tsc_test.c:74] [closeToNativeRdtsc] ddcycles: 362 error:0.000024%
2: ok 1 /tsc/rdtscIsCloseToNative
2: 00:00:00.500477 trace [tsc.c:43] [_frequency_via_cpuid] rax 657060 -> family_id:0x6 extended_model_id:0xa model:0xa
2: 00:00:00.500482 debug [tsc.c:59] [_frequency_via_cpuid] cpuid 0x15 denominator:2 numerator:156 core:38400000
2: 00:00:00.500486 debug [tsc.c:63] [_frequency_via_cpuid] cpuid 0x16 reports base frequency 3000 MHz
2: 00:00:00.500488 debug [tsc.c:126] [_frequency_via_cpuid] Calculated 2995200000 cyclesPerSecond via cpuid 15h
2: 00:00:01.000652 trace [tsc_test.c:64] [closeToNativeRdtsc] Real dt: 0.500158570
2: 00:00:01.000669 trace [tsc_test.c:66] [closeToNativeRdtsc] Real # cycles: 1498076874
2: 00:00:01.000672 trace [tsc_test.c:71] [closeToNativeRdtsc] Emulated # cycles: 1498074948
2: 00:00:01.000674 trace [tsc_test.c:74] [closeToNativeRdtsc] ddcycles: 1926 error:0.000129%
2: ok 2 /tsc/rdtscpIsCloseToNative
2: # End of tsc tests
1/1 Test #2: tsc_test .........................   Passed    1.00 sec

@sporksmith
Copy link
Copy Markdown
Contributor Author

Looks like this fixes the TSC accuracy for the latest user report: #1519 (comment)

@sporksmith sporksmith requested a review from a team April 1, 2026 17:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Component: Libraries Support functions like LD_PRELOAD and logging Component: Testing Unit and integration tests and frameworks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

new tsc_test fails on my machine

1 participant