Last active
March 22, 2022 03:15
-
-
Save StrikerX3/233afa758a1fc3153f7c531efad8064f to your computer and use it in GitHub Desktop.
Get approximate TSC frequency on Windows
This file contains 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) | |
#include <Windows.h> | |
int main() { | |
LARGE_INTEGER freq; | |
QueryPerformanceFrequency(&freq); | |
printf("QPC Frequency: %I64d\n", freq.QuadPart); | |
LARGE_INTEGER start; | |
LARGE_INTEGER now; | |
unsigned __int64 first = __rdtsc(); | |
QueryPerformanceCounter(&start); | |
for (;;) { | |
unsigned __int64 i = __rdtsc(); | |
QueryPerformanceCounter(&now); | |
printf_s("\r%I64d ticks", i); | |
if (now.QuadPart - start.QuadPart >= freq.QuadPart) { | |
printf_s("\rMeasured frequency: %I64d\n", i - first); | |
start = now; | |
first = i; | |
} | |
} | |
} |
This file contains 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
// A more complete and accurate measurement | |
#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[4] & 0x100) { | |
printf("Host has invariant TSC\n"); | |
} | |
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