3 * tests overhead of timing calls and their monotonicity: that
4 * they always move forward
7 #include "postgres_fe.h"
9 #include "getopt_long.h"
10 #include "portability/instr_time.h"
12 static const char *progname;
14 static int32 test_duration = 3;
16 static void handle_args(int argc, char *argv[]);
17 static uint64 test_timing(int32);
18 static void output(uint64 loop_count);
20 /* record duration in powers of 2 microseconds */
24 main(int argc, char *argv[])
28 progname = get_progname(argv[0]);
30 handle_args(argc, argv);
32 loop_count = test_timing(test_duration);
40 handle_args(int argc, char *argv[])
42 static struct option long_options[] = {
43 {"duration", required_argument, NULL, 'd'},
47 int option; /* Command line option */
48 int optindex = 0; /* used by getopt_long */
52 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
54 printf("Usage: %s [-d DURATION]\n", progname);
57 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
59 puts("pg_test_timing (PostgreSQL) " PG_VERSION);
64 while ((option = getopt_long(argc, argv, "d:",
65 long_options, &optindex)) != -1)
70 test_duration = atoi(optarg);
74 fprintf(stderr, "Try \"%s --help\" for more information.\n",
84 "%s: too many command-line arguments (first is \"%s\")\n",
85 progname, argv[optind]);
86 fprintf(stderr, "Try \"%s --help\" for more information.\n",
91 if (test_duration > 0)
93 printf("Testing timing overhead for %d seconds.\n", test_duration);
98 "%s: duration must be a positive integer (duration is \"%d\")\n",
99 progname, test_duration);
100 fprintf(stderr, "Try \"%s --help\" for more information.\n",
107 test_timing(int32 duration)
110 int64 time_elapsed = 0;
111 uint64 loop_count = 0;
114 instr_time start_time,
118 total_time = duration > 0 ? duration * INT64CONST(1000000) : 0;
120 INSTR_TIME_SET_CURRENT(start_time);
121 cur = INSTR_TIME_GET_MICROSEC(start_time);
123 while (time_elapsed < total_time)
129 INSTR_TIME_SET_CURRENT(temp);
130 cur = INSTR_TIME_GET_MICROSEC(temp);
133 /* Did time go backwards? */
136 printf("Detected clock going backwards in time.\n");
137 printf("Time warp: %d microseconds\n", diff);
141 /* What is the highest bit in the time diff? */
148 /* Update appropriate duration bucket */
152 INSTR_TIME_SUBTRACT(temp, start_time);
153 time_elapsed = INSTR_TIME_GET_MICROSEC(temp);
156 INSTR_TIME_SET_CURRENT(end_time);
158 INSTR_TIME_SUBTRACT(end_time, start_time);
160 printf("Per loop time including overhead: %0.2f nsec\n",
161 INSTR_TIME_GET_DOUBLE(end_time) * 1e9 / loop_count);
167 output(uint64 loop_count)
172 /* find highest bit value */
173 while (max_bit > 0 && histogram[max_bit] == 0)
176 printf("Histogram of timing durations:\n");
177 printf("%6s %10s %10s\n", "< usec", "% of total", "count");
179 for (i = 0; i <= max_bit; i++)
183 /* lame hack to work around INT64_FORMAT deficiencies */
184 snprintf(buf, sizeof(buf), INT64_FORMAT, histogram[i]);
185 printf("%6ld %9.5f %10s\n", 1l << i,
186 (double) histogram[i] * 100 / loop_count, buf);