Last active
October 13, 2023 16:36
-
-
Save StrikerX3/c403856c25c883be809e765187df8914 to your computer and use it in GitHub Desktop.
Get TSC frequency on Windows
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <intrin.h> | |
#pragma intrinsic(__cpuid) | |
int main() { | |
int id[4]; | |
__cpuid(id, 0x15); | |
auto tscFreq = (__int64)id[2] * id[1] / id[0]; | |
printf("TSC frequency: %I64d Hz (%I64d MHz)\n", tscFreq, tscFreq / 1000000ULL); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <intrin.h> | |
#pragma intrinsic(__rdtsc) | |
#pragma intrinsic(__cpuid) | |
#include <Windows.h> | |
int main() { | |
LARGE_INTEGER freqQPC; | |
QueryPerformanceFrequency(&freqQPC); | |
printf("QPC Frequency: %I64d\n", freqQPC.QuadPart); | |
int id[4]; | |
__cpuid(id, 0x80000007); | |
if (id[3] & 0x100) { | |
printf("Host has invariant TSC\n"); | |
} | |
__cpuid(id, 0x15); | |
auto tscFreq = (__int64)id[2] * id[1] / id[0]; | |
printf("Calculated TSC frequency: %I64d Hz (%I64d MHz)\n", tscFreq, tscFreq / 1000000ULL); | |
LARGE_INTEGER startQPC; | |
LARGE_INTEGER prevQPC; | |
QueryPerformanceCounter(&startQPC); | |
prevQPC = startQPC; | |
unsigned __int64 startTSC = __rdtsc(); | |
unsigned __int64 prevTSC = startTSC; | |
for (;;) { | |
LARGE_INTEGER nowQPC; | |
QueryPerformanceCounter(&nowQPC); | |
if (nowQPC.QuadPart - prevQPC.QuadPart >= freqQPC.QuadPart / 3) { | |
unsigned __int64 nowTSC = __rdtsc(); | |
unsigned __int64 deltaTSC = (nowTSC - prevTSC); | |
LONGLONG deltaQPC = (nowQPC.QuadPart - prevQPC.QuadPart); | |
unsigned __int64 freqComputed = deltaTSC * freqQPC.QuadPart / deltaQPC; | |
unsigned __int64 freqMHz = freqComputed / 1000000ULL + (freqComputed % 1000000ULL >= 500000ULL ? 1 : 0); | |
unsigned __int64 deltaStartTSC = (nowTSC - startTSC); | |
LONGLONG deltaStartQPC = (nowQPC.QuadPart - startQPC.QuadPart); | |
unsigned __int64 freqAvgComputed = deltaStartTSC * freqQPC.QuadPart / deltaStartQPC; | |
unsigned __int64 freqAvgMHz = freqAvgComputed / 1000000ULL + (freqAvgComputed % 1000000ULL >= 500000ULL ? 1 : 0); | |
printf_s("Measured frequency: %I64d Hz (%I64d MHz) Average: %I64d Hz (%I64d MHz)\n", freqComputed, freqMHz, freqAvgComputed, freqAvgMHz); | |
prevQPC = nowQPC; | |
prevTSC = nowTSC; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment