-rw-r--r-- 1792 djbsort-20180717/cpucycles/vct/cpucycles.c
#include <time.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/time.h> #include <sys/types.h> #include "osfreq.c" #include "cpucycles.h" static long myround(double u) { long result = u; while (result + 0.5 < u) result += 1; while (result - 0.5 > u) result -= 1; return result; } static long long microseconds(void) { struct timeval t; gettimeofday(&t,(struct timezone *) 0); return t.tv_sec * (long long) 1000000 + t.tv_usec; } static int tbshift = 0; static long long timebase(void) { unsigned long long result; asm volatile("mrs %0, CNTVCT_EL0" : "=r" (result)); return result >> tbshift; } static double cpufrequency = 0; static long tbcycles = 0; static double guesstbcycles(void) { long long tb0; long long us0; long long tb1; long long us1; tb0 = timebase(); us0 = microseconds(); do { tb1 = timebase(); us1 = microseconds(); } while (us1 - us0 < 10000 || tb1 - tb0 < 1000); if (tb1 <= tb0) return 0; tb1 -= tb0; us1 -= us0; return (cpufrequency * 0.000001 * (double) us1) / (double) tb1; } static void init(void) { int loop; double guess1; double guess2; cpufrequency = osfreq(); if (!cpufrequency) return; for (tbshift = 0;tbshift < 10;++tbshift) { for (loop = 0;loop < 100;++loop) { guess1 = guesstbcycles(); guess2 = guesstbcycles(); tbcycles = myround(guess1); if (guess1 - tbcycles > 0.1) continue; if (tbcycles - guess1 > 0.1) continue; if (guess2 - tbcycles > 0.1) continue; if (tbcycles - guess2 > 0.1) continue; return; } } tbcycles = 0; } long long cpucycles(void) { if (!tbcycles) init(); return timebase() * tbcycles; } long long cpucycles_persecond(void) { if (!tbcycles) init(); return cpufrequency; }