00001
00002
00003
00004
00005
00006
00007 #include "postgres_fe.h"
00008
00009 #include "getopt_long.h"
00010 #include "portability/instr_time.h"
00011
00012 static const char *progname;
00013
00014 static int32 test_duration = 3;
00015
00016 static void handle_args(int argc, char *argv[]);
00017 static uint64 test_timing(int32);
00018 static void output(uint64 loop_count);
00019
00020
00021 int64 histogram[32];
00022
00023 int
00024 main(int argc, char *argv[])
00025 {
00026 uint64 loop_count;
00027
00028 progname = get_progname(argv[0]);
00029
00030 handle_args(argc, argv);
00031
00032 loop_count = test_timing(test_duration);
00033
00034 output(loop_count);
00035
00036 return 0;
00037 }
00038
00039 static void
00040 handle_args(int argc, char *argv[])
00041 {
00042 static struct option long_options[] = {
00043 {"duration", required_argument, NULL, 'd'},
00044 {NULL, 0, NULL, 0}
00045 };
00046
00047 int option;
00048 int optindex = 0;
00049
00050 if (argc > 1)
00051 {
00052 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0 ||
00053 strcmp(argv[1], "-?") == 0)
00054 {
00055 printf("Usage: %s [-d DURATION]\n", progname);
00056 exit(0);
00057 }
00058 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
00059 {
00060 puts("pg_test_timing (PostgreSQL) " PG_VERSION);
00061 exit(0);
00062 }
00063 }
00064
00065 while ((option = getopt_long(argc, argv, "d:",
00066 long_options, &optindex)) != -1)
00067 {
00068 switch (option)
00069 {
00070 case 'd':
00071 test_duration = atoi(optarg);
00072 break;
00073
00074 default:
00075 fprintf(stderr, "Try \"%s --help\" for more information.\n",
00076 progname);
00077 exit(1);
00078 break;
00079 }
00080 }
00081
00082 if (argc > optind)
00083 {
00084 fprintf(stderr,
00085 "%s: too many command-line arguments (first is \"%s\")\n",
00086 progname, argv[optind]);
00087 fprintf(stderr, "Try \"%s --help\" for more information.\n",
00088 progname);
00089 exit(1);
00090 }
00091
00092 if (test_duration > 0)
00093 {
00094 printf("Testing timing overhead for %d seconds.\n", test_duration);
00095 }
00096 else
00097 {
00098 fprintf(stderr,
00099 "%s: duration must be a positive integer (duration is \"%d\")\n",
00100 progname, test_duration);
00101 fprintf(stderr, "Try \"%s --help\" for more information.\n",
00102 progname);
00103 exit(1);
00104 }
00105 }
00106
00107 static uint64
00108 test_timing(int32 duration)
00109 {
00110 uint64 total_time;
00111 int64 time_elapsed = 0;
00112 uint64 loop_count = 0;
00113 uint64 prev, cur;
00114 instr_time start_time, end_time, temp;
00115
00116 total_time = duration > 0 ? duration * 1000000 : 0;
00117
00118 INSTR_TIME_SET_CURRENT(start_time);
00119 cur = INSTR_TIME_GET_MICROSEC(start_time);
00120
00121 while (time_elapsed < total_time)
00122 {
00123 int32 diff, bits = 0;
00124
00125 prev = cur;
00126 INSTR_TIME_SET_CURRENT(temp);
00127 cur = INSTR_TIME_GET_MICROSEC(temp);
00128 diff = cur - prev;
00129
00130
00131 if (diff < 0)
00132 {
00133 printf("Detected clock going backwards in time.\n");
00134 printf("Time warp: %d microseconds\n", diff);
00135 exit(1);
00136 }
00137
00138
00139 while (diff)
00140 {
00141 diff >>= 1;
00142 bits++;
00143 }
00144
00145
00146 histogram[bits]++;
00147
00148 loop_count++;
00149 INSTR_TIME_SUBTRACT(temp, start_time);
00150 time_elapsed = INSTR_TIME_GET_MICROSEC(temp);
00151 }
00152
00153 INSTR_TIME_SET_CURRENT(end_time);
00154
00155 INSTR_TIME_SUBTRACT(end_time, start_time);
00156
00157 printf("Per loop time including overhead: %0.2f nsec\n",
00158 INSTR_TIME_GET_DOUBLE(end_time) * 1e9 / loop_count);
00159
00160 return loop_count;
00161 }
00162
00163 static void
00164 output(uint64 loop_count)
00165 {
00166 int64 max_bit = 31, i;
00167
00168
00169 while (max_bit > 0 && histogram[max_bit] == 0)
00170 max_bit--;
00171
00172 printf("Histogram of timing durations:\n");
00173 printf("%6s %10s %10s\n", "< usec", "% of total", "count");
00174
00175 for (i = 0; i <= max_bit; i++)
00176 {
00177 char buf[100];
00178
00179
00180 snprintf(buf, sizeof(buf), INT64_FORMAT, histogram[i]);
00181 printf("%6ld %9.5f %10s\n", 1l << i,
00182 (double) histogram[i] * 100 / loop_count, buf);
00183 }
00184 }