clock_test.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. * clock_test. A simple program to test the latency of the clock_gettime() call
  3. *
  4. * Compile: gcc clock_test.c -lm -o clock_test
  5. *
  6. * Written by: Gary E. Miller <gem@rellim.com>
  7. * This file is Copyright 2018 by the GPSD project
  8. * SPDX-License-Identifier: BSD-2-clause
  9. */
  10. #include <getopt.h> /* for getopt() */
  11. #include <limits.h> /* for LONG_MAX */
  12. #include <math.h> /* for pow(), sqrt() */
  13. #include <stdio.h> /* for printf() */
  14. #include <stdlib.h> /* for qsort() */
  15. #include <time.h> /* for time_t */
  16. #define NUM_TESTS 101 /* default samples, make it odd for a clean median */
  17. #define DELAY 10000000 /* default delay between samples in ns, 10 ms is good */
  18. int compare_long( const void *ap, const void *bp)
  19. {
  20. long a = *((long *)ap);
  21. long b = *((long *)bp);
  22. if ( a < b ) return -1;
  23. if ( a > b ) return 1;
  24. return 0;
  25. }
  26. int main(int argc, char **argv)
  27. {
  28. int i;
  29. int opt; /* for getopts() */
  30. int verbose = 0;
  31. int samples = NUM_TESTS;
  32. long delay = DELAY;
  33. long *diffs = NULL;
  34. long min = LONG_MAX, max = 0, sum = 0, mean = 0, median = 0;
  35. double stddev = 0.0;
  36. while ((opt = getopt(argc, argv, "d:hvn:")) != -1) {
  37. switch (opt) {
  38. case 'd':
  39. delay = atol(optarg);
  40. break;
  41. case 'n':
  42. samples = atoi(optarg);
  43. /* make odd, for a good median */
  44. if ( (samples & 1) == 0) {
  45. samples += 1;
  46. }
  47. break;
  48. case 'v':
  49. verbose = 1;
  50. break;
  51. case 'h':
  52. /* fall through */
  53. default: /* '?' */
  54. fprintf(stderr, "Usage: %s [-h] [-d nsec] [-n samples] [-v]\n\n", argv[0]);
  55. fprintf(stderr, "-d nsec : nano seconde paus between samples\n");
  56. fprintf(stderr, "-h : help\n");
  57. fprintf(stderr, "-n samples : Number of samples, default %d\n", NUM_TESTS);
  58. fprintf(stderr, "-v : verbose\n");
  59. exit(EXIT_FAILURE);
  60. }
  61. }
  62. diffs = alloca( sizeof(long) * (samples + 2)); /* add 2 for off by one errors */
  63. /* collect test data */
  64. for ( i = 0 ; i < samples; i++ ) {
  65. struct timespec now, now1, sleep, sleep1;
  66. (void)clock_gettime(CLOCK_REALTIME, &now);
  67. (void)clock_gettime(CLOCK_REALTIME, &now1);
  68. diffs[i] = now1.tv_nsec - now.tv_nsec;
  69. if ( now1.tv_sec != now.tv_sec ) {
  70. /* clock roll over, fix it */
  71. diffs[i] += 1000000000; /* add one second */
  72. }
  73. /* instead of hammering, sleep between tests, let the cache get cold */
  74. sleep.tv_sec = 0;
  75. sleep.tv_nsec = delay; /* sleep delay */
  76. /* sleep1 unused, should not be returning early */
  77. nanosleep(&sleep, &sleep1);
  78. }
  79. /* analyze test data */
  80. /* print diffs, calculate min and max */
  81. for ( i = 0 ; i < samples; i++ ) {
  82. if ( verbose > 0 ) {
  83. printf("diff %ld\n", diffs[i]);
  84. }
  85. sum += diffs[i];
  86. if ( diffs[i] < min ) min = diffs[i];
  87. if ( diffs[i] > max ) max = diffs[i];
  88. }
  89. mean = sum / (samples - 1);
  90. qsort( diffs, samples, sizeof(long), compare_long);
  91. median = diffs[(samples / 2) + 1];
  92. for ( i = 0 ; i < samples; i++ ) {
  93. stddev += pow(diffs[i] - mean, 2);
  94. }
  95. stddev = sqrt(stddev/samples);
  96. printf("samples %d, delay %ld ns\n", samples, delay);
  97. printf("min %ld ns, max %ld ns, mean %ld ns, median %ld ns, StdDev %ld ns\n",
  98. min, max, mean, median, (long)stddev);
  99. }