[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [Libevent-users] Strange timeout scheduling in 1.4



On Wed, Jul 27, 2011 at 11:00:45PM -0400, Nick Mathewson wrote:
> On Wed, Jul 27, 2011 at 10:35 PM, William Ahern
> <william@xxxxxxxxxxxxxxxxxx> 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 majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.