From 598b8b9bc743ac3f03e0580be9fd222b4412a469 Mon Sep 17 00:00:00 2001 From: "Gary E. Miller" Date: Thu, 25 Jan 2018 17:15:20 -0800 Subject: Add clock_test in contrib. clock_test checks the latency of the clock_gettime() system call. --- contrib/clock_test.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 contrib/clock_test.c (limited to 'contrib/clock_test.c') diff --git a/contrib/clock_test.c b/contrib/clock_test.c new file mode 100644 index 00000000..904c9678 --- /dev/null +++ b/contrib/clock_test.c @@ -0,0 +1,110 @@ +/* + * clock_test. A simple program to test the latency of the clock_gettime() call + * + * Compile: gcc clock_test.c -lm -o clock_test + * + */ + +#include /* for getopt() */ +#include /* for LONG_MAX */ +#include /* for pow(), sqrt() */ +#include /* for printf() */ +#include /* for qsort() */ +#include /* for time_t */ + +#define NUM_TESTS 101 /* default samples, make it odd for a clean median */ +#define DELAY 10000000 /* default delay between samples in ns, 10 ms is good */ + +int compare_long( const void *ap, const void *bp) +{ + long a = *((long *)ap); + long b = *((long *)bp); + if ( a < b ) return -1; + if ( a > b ) return 1; + return 0; +} + +int main(int argc, char **argv) +{ + int i; + int opt; /* for getopts() */ + int verbose = 0; + int samples = NUM_TESTS; + long delay = DELAY; + long *diffs = NULL; + long min = LONG_MAX, max = 0, sum = 0, mean = 0, median = 0; + double stddev = 0.0; + + while ((opt = getopt(argc, argv, "d:hvn:")) != -1) { + switch (opt) { + case 'd': + delay = atol(optarg); + break; + case 'n': + samples = atoi(optarg); + /* make odd, for a good median */ + if ( (samples & 1) == 0) { + samples += 1; + } + break; + case 'v': + verbose = 1; + break; + case 'h': + /* fall through */ + default: /* '?' */ + fprintf(stderr, "Usage: %s [-h] [-d nsec] [-n samples] [-v]\n\n", argv[0]); + fprintf(stderr, "-d nsec : nano seconde paus between samples\n"); + fprintf(stderr, "-h : help\n"); + fprintf(stderr, "-n samples : Number of samples, default %d\n", NUM_TESTS); + fprintf(stderr, "-v : verbose\n"); + exit(EXIT_FAILURE); + } + } + + diffs = alloca( sizeof(long) * (samples + 2)); /* add 2 for off by one errors */ + + /* collect test data */ + for ( i = 0 ; i < samples; i++ ) { + struct timespec now, now1, sleep, sleep1; + + (void)clock_gettime(CLOCK_REALTIME, &now); + (void)clock_gettime(CLOCK_REALTIME, &now1); + diffs[i] = now1.tv_nsec - now.tv_nsec; + if ( now1.tv_sec != now.tv_sec ) { + /* clock roll over, fix it */ + diffs[i] += 1000000000; /* add one second */ + } + /* instead of hammering, sleep between tests, let the cache get cold */ + sleep.tv_sec = 0; + sleep.tv_nsec = delay; /* sleep delay */ + /* sleep1 unused, should not be returning early */ + nanosleep(&sleep, &sleep1); + } + + /* analyze test data */ + + /* print diffs, calculate min and max */ + for ( i = 0 ; i < samples; i++ ) { + if ( verbose > 0 ) { + printf("diff %ld\n", diffs[i]); + } + sum += diffs[i]; + if ( diffs[i] < min ) min = diffs[i]; + if ( diffs[i] > max ) max = diffs[i]; + } + mean = sum / (samples - 1); + + qsort( diffs, samples, sizeof(long), compare_long); + median = diffs[(samples / 2) + 1]; + + + for ( i = 0 ; i < samples; i++ ) { + stddev += pow(diffs[i] - mean, 2); + } + stddev = sqrt(stddev/samples); + + printf("samples %d, delay %ld ns\n", samples, delay); + printf("min %ld ns, max %ld ns, mean %ld ns, median %ld ns, StdDev %ld ns\n", + min, max, mean, median, (long)stddev); +} -- cgit v1.2.1