For an assignment, I’ve been trying to work on a project to inspect and retrieve system information on Linux either in pure C, or inline ASM. A bit of a problem I’m having now is actually retrieving the clockspeed.
I initially attempted to just read from __cpuid
:
__cpuid(0x80000002 + i, eax, ebx, ecx, edx);
I do not believe on AMD CPUs, the Clockspeed is incorporated in this string. Now, I am using rdtsc
to retrieve a pretty accurate figure, but the more I reduce the busy-wait loop’s time, the more accuracy I am losing. So far this is what I’ve come up with:
static inline uint64_t rdtsc() {
unsigned int lo, hi;
asm volatile ("rdtsc" : "=a" (lo), "=d" (hi));
return ((uint64_t)hi << 32) | lo;
}
void calculate_cpu_clock_speed() {
uint64_t start, end;
struct timespec ts_start, ts_end;
double elapsed_time;
// Get TSC and time at start
start = rdtsc();
clock_gettime(CLOCK_MONOTONIC, &ts_start);
// (~1 ms)
do {
clock_gettime(CLOCK_MONOTONIC, &ts_end);
elapsed_time = (ts_end.tv_sec - ts_start.tv_sec) +
(ts_end.tv_nsec - ts_start.tv_nsec) / 1e9;
} while (elapsed_time < 0.001);
end = rdtsc();
(cycles per second -> Hz -> GHz)
double clock_speed_hz = (end - start) / elapsed_time;
double clock_speed_ghz = clock_speed_hz / 1e9;
printf("%.1f0 GHz\n", clock_speed_ghz);
}
Is there any chance at getting this faster?
You need to sign in to view this answers