alpha.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*
  2. cpucycles/alpha.c version 20060316
  3. D. J. Bernstein
  4. Public domain.
  5. */
  6. #include <time.h>
  7. #include <unistd.h>
  8. #include <sys/time.h>
  9. static long long tod(void)
  10. {
  11. struct timeval t;
  12. gettimeofday(&t,(struct timezone *) 0);
  13. return t.tv_sec * (long long) 1000000 + t.tv_usec;
  14. }
  15. static long long rpcc(void)
  16. {
  17. unsigned long long t;
  18. asm volatile("rpcc %0" : "=r"(t));
  19. return t & 0xffffffff;
  20. }
  21. static long long firstrpcc;
  22. static long long firsttod;
  23. static long long lastrpcc;
  24. static long long lasttod;
  25. static double mhz = 0;
  26. static void init(void)
  27. {
  28. firstrpcc = rpcc();
  29. firsttod = tod();
  30. do {
  31. lastrpcc = rpcc();
  32. lasttod = tod();
  33. } while (lasttod - firsttod < 10000);
  34. lastrpcc -= firstrpcc; lastrpcc &= 0xffffffff;
  35. lasttod -= firsttod;
  36. mhz = (double) lastrpcc / (double) lasttod;
  37. }
  38. long long cpucycles_alpha(void)
  39. {
  40. double x;
  41. long long y;
  42. if (!mhz) init();
  43. lastrpcc = rpcc();
  44. lasttod = tod();
  45. lastrpcc -= firstrpcc; lastrpcc &= 0xffffffff;
  46. lasttod -= firsttod;
  47. /* Number of cycles since firstrpcc is lastrpcc + 2^32 y for unknown y. */
  48. /* Number of microseconds since firsttod is lasttod. */
  49. x = (lasttod * mhz - lastrpcc) * 0.00000000023283064365386962890625;
  50. y = x;
  51. while (x > y + 0.5) y += 1;
  52. while (x < y - 0.5) y -= 1;
  53. y *= 4294967296ULL;
  54. lastrpcc += y;
  55. mhz = (double) lastrpcc / (double) lasttod;
  56. return firstrpcc + lastrpcc;
  57. }
  58. long long cpucycles_alpha_persecond(void)
  59. {
  60. if (!mhz) init();
  61. return 1000000.0 * mhz;
  62. }