Skip to content

Instantly share code, notes, and snippets.

@StrikerX3
Last active March 22, 2022 03:15
Show Gist options
  • Save StrikerX3/233afa758a1fc3153f7c531efad8064f to your computer and use it in GitHub Desktop.
Save StrikerX3/233afa758a1fc3153f7c531efad8064f to your computer and use it in GitHub Desktop.
Get approximate TSC frequency on Windows
#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;
}
}
}
// 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