Using High-resolution Timers

tandard C++ offers a rather limited number of functions for accurate time measurement: clock() gives you a granularity of up to a thousandth of a second at best, and difftime() compares two different time() readings. However, when it comes to multimedia streaming, games and profiling, you want higher resolution timers. The following sections present POSIX high-resolution timers. These timers are available on POSIX systems and to some extent, on Windows, too.

You need high-resolution timers that measure microseconds and even nanoseconds. However, the standard facilities are a long way from providing that kind of capability.

When the ISO C++ standard doesn’t provide the answers, use another portable and reliable standard library?POSIX.

Time and time() Again
Applications that need a high-resolution time measurement can use the quasi-portable gettimeofday() function defined by the POSIX standard and also available on most versions of Windows. gettimeofday() is declared in the header:

int gettimeofday (struct timeval *tp, void*);

It writes to tp the number of seconds that have elapsed since the epoch, i.e., 01/01/1970 00:00:00. Unlike time(), which uses a one-second granularity, gettimeofday() expresses the current timestamp in seconds and microseconds (millionths of a second) since the epoch. As with may other time-measuring functions, the actual resolution of gettimeofday() depends on the underlying hardware of your machine, so you shouldn’t assume that every platform supporting gettimeofday() will necessarily have a microsecond granularity.

gettimeofday() writes the current timestamp into a timeval data structure:

struct timeval{ time_t tv_sec; //seconds suseconds_t tv_usec; //microseconds};

The following code listing obtains the current timestamp using gettimeofday() and displays it onscreen:

#include  #include int main(){ struct timeval tv; gettimeofday(&tv,0); std::cout<<"the current timestamp is: "   <

A granularity of one millionth of a second sounds impressive, yet some applications require even higher. Timers with a resolution of a nanosecond are now available on real-time POSIX systems.

Nanosecond Granularity
High-resolution timers rely on the fact that modern processors have a clock rate of at least one billion cycles per second. An implementation can use the ticks of the system's processor (or a dedicated processor used exclusively for time measurement) to create a timer with a nanosecond granularity.

The real-time POSIX standard defines the gethrtime() function which offers a nanosecond granularity, at least in theory. Solaris, AIX, real-time variants of Linux and several other POSIX implementations already support this function:

 hrtime_t gethrtime(void);

gethrtime() returns the value of a high resolution timer that started counting time since some arbitrary time in the past (typically, the timer starts measuring time since the most recent system booting). gethrtime() reports the time as the number of nanoseconds elapsed since that arbitrary moment in the past. The typedef hrtime_t is a 64-bit signed integer. The high-resolution timer used by gethrtime() is not correlated in any way to the time of day; therefore it's not subject to resetting or being manipulated by adjtime() and settimeofday() calls.

The constant HRTIME_INFINITY represents the maximum possible value that gethrtime() could return. The HRTIME_INFINITY value will never be reached during the execution of the current process. Therefore, you can use this constant to designate the infinitely distant moment in time.

Although the return value of gethrtime() is expressed as nanoseconds, the actual granularity is hardware-dependent and may be coarser than that. If two consecutive calls to gethrtime() take place very proximately, you could still get identical results on certain hardware architectures. However, there are some guarantees:

  • Monotonicity. The later of two consecutive gethrtime() calls will not decrease. In addition, the result of gethrtime() will not roll over.
  • Linearity. These functions won't speed up or slow down; they are independent of system load and other performance issues that may affect time(), clock(), or gettimeofday().

The cost of calling gethrtime() is low: three CPU cycles or even less. As such, frequent gethrtime() calls during profiling or testing have minimal effect on the performance of the process being profiled.

The following code listing measures the average time in nanoseconds needed for executing a getpid() call using gethrtime():

int main(){ hrtime_t start, end; start = gethrtime();  for (int n = 0; n < 10; n++)   getpid(); end = gethrtime(); printf("%lld nsec
 on average", (end - start) / 10);}
Share the Post:
Share on facebook
Share on twitter
Share on linkedin


Recent Articles: