On Wed, Jul 27, 2011 at 11:00:45PM -0400, Nick Mathewson wrote:
> On Wed, Jul 27, 2011 at 10:35 PM, William Ahern
> <will...@25thandclement.com> wrote:
> 
> If you happen to know, is it the same story with clock_gettime()
> performance?  I ask because Libevent uses that function in preference
> to gettimeofday() when it's available.

I quickly ran some tests. Results:

OpenBSD AMD64 4.8: No difference between gettimeofday and clock_gettime.
Both just end up calling bintime() in kern_tc.c. Crazy slow.

Linux x86_64 2.6.35: No difference. In the 3.0 tree gettimeofday() and
CLOCK_REALTIME both just call do_realtime() in
arch/x86/vdso/vclock_gettime.c. CLOCK_MONOTONIC calls do_monotonic() which
is similar code.

Linux x86_64 2.6.30: No difference

Linux i686 2.6.30: gettimeofday() was slightly faster than clock_gettime(),
but I had to crank the iterations up to 20M to really see it. No difference
between CLOCK_REALTIME and CLOCK_MONOTONIC. All of this code seems to reside
in kernel/time/ and kernel/posix-timers.c in the 3.0 tree. clock_gettime()
calls a bunch of function pointers but it _seems_ that it probably ends up
calling getnstimeofday() like gettimeofday(), so the cost difference might
just be because of the indirection of the POSIX timers implementation.

OS X 10.8.0: gettimeofday() as fast as on x86_64 Linux, with all the time
spent in userspace, so they must be doing something similar with reading a
mapped, cached value and offsetting with the CPU TSC.


Here's my code. Linux requires -lrt to find clock_getttime(). Usage:

        time ./gtod -i 10M [gtod|rt|mt]

/* gtod.c */
#include <stdlib.h>

#include <string.h>

#include <time.h>

#include <sys/time.h>

#include <unistd.h>

#include <err.h>


int main(int argc, char *argv[]) {
        extern char *optarg;
        extern int optind;
        int opt;
        struct timeval tv;
        struct timespec ts;
        unsigned i = 1U<<20;
        const char *mode;

        while (-1 != (opt = getopt(argc, argv, "i:"))) {
                switch (opt) {
                case 'i':
                        i = 0;

                        for (; *optarg; optarg++) {
                                switch (*optarg) {
                                case '0' ... '9':
                                        i *= 10;
                                        i += *optarg - '0';

                                        break;
                                case 'M': case 'm':
                                        i *= 1U<<20;

                                        break;
                                case 'K': case 'k':
                                        i *= 1U<<10;

                                        break;
                                }
                        }

                        break;
                }
        }

        mode = (argv[optind])? : "gtod";

        if (!strcmp(mode, "gtod")) {
                while (i--) {
                        gettimeofday(&tv, 0);
                        __asm__("");
                }
#if defined(CLOCK_REALTIME)
        } else if (!strcmp(mode, "rt")) {
                while (i--) {
                        clock_gettime(CLOCK_REALTIME, &ts);
                        __asm__("");
                }
#endif
#if defined(CLOCK_MONOTONIC)
        } else if (!strcmp(mode, "mt")) {
                while (i--) {
                        clock_gettime(CLOCK_MONOTONIC, &ts);
                        __asm__("");
                }
#endif
        } else {
                errx(EXIT_FAILURE, "%s: unknown mode", mode);
        }

        return 0;
} /* main() */

***********************************************************************
To unsubscribe, send an e-mail to majord...@freehaven.net with
unsubscribe libevent-users    in the body.

Reply via email to