-
Notifications
You must be signed in to change notification settings - Fork 2
gettimeofday vs clock_gettime
The gettimeofday() is the function used in exsdk for timing. Here is a discussion about the difference between it and clock_gettime(), also show the disadvantage in using it. --- Is gettimeofday() guaranteed to be of microsecond resolution?
I quote some of the comments here:
- clock_gettime is present only on newest Linux. other system have only gettimeofday() – vitaly.v.ch Dec 18 '09 at 16:23
- Wine is actually using gettimeofday() to implement QueryPerformanceCounter() and it is known to make many Windows games work on Linux and Mac.
My conclusion is, the mac-osx doesn't support clock_gettime() so you don't have too much choice but use gettimeofday(), and it is not that bad in my experience.
High Resolution Time Measurement and Timers, Part I
Standard C++ inherited the time and date library from C. While this library offers many useful time and date facilities, it doesn’t support a high-resolution time measurement. The POSIX standard defines extensions to this library which are capable of measuring time in microseconds (millionths of a second) and even nanoseconds (billionths of a second). Let’s see how they are used.
First, let’s look at a quick reminder. In standard C and C++, you use the time() function to obtain the current timestamp. The time is represented as the number of seconds that have elapsed since The Epoch, or 1/1/1970 at midnight. In a typical 32 bit system, time_t will rollover in 2038. However, as more platforms are gradually moving to a 64 bit time_t, this time bomb so to speak will have disappeared by then.
POSIX defines a fine-grained time measuring function called gettimeofday():
#include <sys/time.h>
#include <unistd.h>
int gettimeofday(struct timeval * tv, struct timezone *tz);If struct timeval looks familiar, it’s because I discussed awhile ago when I explained non-blocking I/O using select(). Its declaration is repeated here for convenience:
struct timeval
{
int tv_sec; /*seconds*/
int tv_usec; /*microseconds*/
};
struct timezone is declared as follows:
struct timezone
{
int tz_mniuteswest; /*minutes west of Greenwich*/
int tz_dsttime; /*dst correction type*/
};The actual resolution of gettimeofday() depends on the hardware architecture. Intel processors as well as SPARC machines offer high resolution timers that measure microseconds. Other hardware architectures fall back to the system’s timer, which is typically set to 100 Hz. In such cases, the time resolution will be less accurate.
The following code listing displays the current timestamp in seconds and microseconds:
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
printf("the current time of day represented as time_t is %d and %d microseconds", tv.tv_sec, tv.tv_usec);A timer is a resource that enables a process or a thread to schedules an event. A program uses a timer to ask the kernel to notify it when a certain amount of time has elapsed. There are two types of timer: synchronous and asynchronous. When a process uses a timer synchronously, it waits until the timer expires, usually by means of calling sleep() or a similar syscall. Sleeping means that the process is removed from the kernel’s scheduler for a certain amount of time. POSIX defines four different functions for sleeping, each of which measures time in different units.
sleep()
sleep() causes the process to sleep at least nsec seconds or until a signal that the process doesn’t ignore is received.
unsigned int sleep (unsigned int nsec);If sleep() hasn’t slept nsec seconds, it returns the number of seconds left. Otherwise, it returns 0. sleep() is mostly useful for polling a certain resource in fixed intervals of time. For example, a mail client that polls its mail server every 10 minutes can use a loop that contains a sleep(600); call. This is also the most common syscall for sleeping.
usleep()
usleep() causes the process to sleep for at least usec microseconds:
void usleep (unsigned long usec);usleep() causes the process to sleep for at least usec microseconds. No signals are used in this case. Most implementations use select() to implement this function. It’s equivalent to calling:
timeval tv;
tv.tv_sec=0;
tv.tv_usec=usec;
int select(0, NULL, NULL, NULL, &tv);nanosleep()
nanosleep() offers a resolution of nanoseconds:
int nanosleep(struct timespec *req, struct timespec * rem); The struct timespec is declared as follows:
struct timspec
{
long int tv_sec; /*as in timeval*/
long int tv_nsec; /*nanoseconds*/
};nanosleep() causes the process to sleep at least the amount of time indicated in req or until a signal is received. If nanosleep() terminates earlier due to a signal it returns -1 and rem is filled with the remaining time. nanosleep() offers the highest resolution (theoretically, up to a billionth of a second) although it’s the least portable of these four functions. This function is mostly used in real-time environments, allowing a process to sleep a precise amount of time.
In the second part of this series I will discuss interval timers, a facility that delivers signals on a regular basis to a process.