MCPcopy Create free account
hub / github.com/PlatformLab/NanoLog / init

Method init

runtime/Cycles.cc:42–93  ·  view source on GitHub ↗

* Perform once-only overall initialization for the Cycles class, such * as calibrating the clock frequency. This method is invoked automatically * during initialization, but it may be invoked explicitly by other modules * to ensure that initialization occurs before those modules initialize * themselves. */

Source from the content-addressed store, hash-verified

40 * themselves.
41 */
42void
43Cycles::init() {
44 if (cyclesPerSec != 0)
45 return;
46
47 // Compute the frequency of the fine-grained CPU timer: to do this,
48 // take parallel time readings using both rdtsc and gettimeofday.
49 // After 10ms have elapsed, take the ratio between these readings.
50
51 struct timeval startTime, stopTime;
52 uint64_t startCycles, stopCycles, micros;
53 double oldCycles;
54
55 // There is one tricky aspect, which is that we could get interrupted
56 // between calling gettimeofday and reading the cycle counter, in which
57 // case we won't have corresponding readings. To handle this (unlikely)
58 // case, compute the overall result repeatedly, and wait until we get
59 // two successive calculations that are within 0.001% of each other (or
60 // in other words, a drift of up to 10µs per second).
61 oldCycles = 0;
62 while (1) {
63 if (gettimeofday(&startTime, NULL) != 0) {
64 PERFUTILS_DIE("Cycles::init couldn't read clock: %s", strerror(errno));
65 }
66 startCycles = rdtsc();
67 while (1) {
68 if (gettimeofday(&stopTime, NULL) != 0) {
69 PERFUTILS_DIE("Cycles::init couldn't read clock: %s",
70 strerror(errno));
71 }
72 stopCycles = rdtsc();
73 micros = (stopTime.tv_usec - startTime.tv_usec) +
74 (stopTime.tv_sec - startTime.tv_sec)*1000000;
75 if (micros > 10000) {
76 cyclesPerSec = static_cast<double>(stopCycles - startCycles);
77 cyclesPerSec = 1000000.0*cyclesPerSec/
78 static_cast<double>(micros);
79 break;
80 }
81 }
82 double delta = cyclesPerSec/100000.0;
83 if ((oldCycles > (cyclesPerSec - delta)) &&
84 (oldCycles < (cyclesPerSec + delta))) {
85 goto exit;
86 }
87 oldCycles = cyclesPerSec;
88 }
89
90 exit:
91 ;
92 //printf("Cycles per second: %f\n", cyclesPerSec);
93}
94
95/**
96 * Return the number of CPU cycles per second.

Callers

nothing calls this directly

Calls 1

rdtscFunction · 0.85

Tested by

no test coverage detected