x86estimate.c 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. #include <time.h>
  2. #include <sys/time.h>
  3. #include <sys/types.h>
  4. #include <sys/sysctl.h>
  5. long long cpucycles_x86estimate(void)
  6. {
  7. long long result;
  8. asm volatile(".byte 15;.byte 49" : "=A" (result));
  9. return result;
  10. }
  11. static long long microseconds(void)
  12. {
  13. struct timeval t;
  14. gettimeofday(&t,(struct timezone *) 0);
  15. return t.tv_sec * (long long) 1000000 + t.tv_usec;
  16. }
  17. static double guessfreq(void)
  18. {
  19. long long tb0; long long us0;
  20. long long tb1; long long us1;
  21. tb0 = cpucycles_x86estimate();
  22. us0 = microseconds();
  23. do {
  24. tb1 = cpucycles_x86estimate();
  25. us1 = microseconds();
  26. } while (us1 - us0 < 10000 || tb1 - tb0 < 1000);
  27. if (tb1 <= tb0) return 0;
  28. tb1 -= tb0;
  29. us1 -= us0;
  30. return ((double) tb1) / (0.000001 * (double) us1);
  31. }
  32. static double cpufrequency = 0;
  33. static void init(void)
  34. {
  35. double guess1;
  36. double guess2;
  37. int loop;
  38. for (loop = 0;loop < 100;++loop) {
  39. guess1 = guessfreq();
  40. guess2 = guessfreq();
  41. if (guess1 > 1.01 * guess2) continue;
  42. if (guess2 > 1.01 * guess1) continue;
  43. cpufrequency = 0.5 * (guess1 + guess2);
  44. break;
  45. }
  46. }
  47. long long cpucycles_x86estimate_persecond(void)
  48. {
  49. if (!cpufrequency) init();
  50. return cpufrequency;
  51. }