Calculating the Processor Clock Frequency

Clock::cpu_mips() calculates the processor clock frequency in Mhz for use in calibrating the processor time stamp counter, which gives much better resolution than API access to the operating system clock. Such counters are standard on modern processors, access to them may be obtained via gcc inline assembler, and such code is wrapped here in the set_time_stamp() call provided in the library, which leaves the problem of calibrating the counter with respect to wall clock time.

The best approach is to compare two processor time stamp counter values after a reasonably predictable delay, here a call to sleep for 1 second, which has the virtues of simplicity, accuracy, precision, and portability, though with an admittedly large time cost.

That cost is acceptable given that it is paid only once, during Clock construction, and that worse problems arise with the alternatives. Shorter time delays, e.g. via select(), have proven much less accurate, and though reading /proc/info is fast and simple, it is not portable.

Since this frequency calibration value affects Scheduler operation, and is used as well for every event time stamp, the correct choice here is to get it right to start with. Although averaging might be used, the likelihood of interrupts increases, and computation must still deal with counter wrap around.

In the procedure Clock::cpu_mips(), a loop is used to eliminate such rollover events, with termination requiring that the processor clock frequency be lower than $2^64$; the risk of the alternative is considered acceptable for the foreseeable future.

In order to avoid the one second startup cost, and reduce the running time of the regression test suite, access to the Clock::cpu_info() function is provided via the "fast" command line option, for test modes only.

Bill Pippin 2010-01-14