@@ -30,7 +30,7 @@ static long long int largest_diff_count;
3030
3131
3232static void handle_args (int argc , char * argv []);
33- static uint64 test_timing (unsigned int duration );
33+ static uint64 test_timing (unsigned int duration , bool fast_timing );
3434static void output (uint64 loop_count );
3535
3636int
@@ -43,10 +43,22 @@ main(int argc, char *argv[])
4343
4444 handle_args (argc , argv );
4545
46- loop_count = test_timing (test_duration );
47-
46+ /*
47+ * First, test default (non-fast) timing code. A clock source for that
48+ * is always available. Hence, we can unconditionally output the result.
49+ */
50+ loop_count = test_timing (test_duration , false);
4851 output (loop_count );
4952
53+ /*
54+ * Second, test the fast timing code. This clock source is not always
55+ * available. In that case the loop count will be 0 and we don't print.
56+ */
57+ printf ("\n" );
58+ loop_count = test_timing (test_duration , true);
59+ if (loop_count > 0 )
60+ output (loop_count );
61+
5062 return 0 ;
5163}
5264
@@ -78,7 +90,7 @@ handle_args(int argc, char *argv[])
7890 }
7991 }
8092
81- while ((option = getopt_long (argc , argv , "d:c:" ,
93+ while ((option = getopt_long (argc , argv , "d:c:f: " ,
8294 long_options , & optindex )) != -1 )
8395 {
8496 switch (option )
@@ -143,23 +155,44 @@ handle_args(int argc, char *argv[])
143155 exit (1 );
144156 }
145157
146- printf (ngettext ("Testing timing overhead for %u second.\n" ,
147- "Testing timing overhead for %u seconds.\n" ,
158+ printf (ngettext ("Testing timing overhead for %u second.\n\n " ,
159+ "Testing timing overhead for %u seconds.\n\n " ,
148160 test_duration ),
149161 test_duration );
150162}
151163
152164static uint64
153- test_timing (unsigned int duration )
165+ test_timing (unsigned int duration , bool fast_timing )
154166{
155167 uint64 total_time ;
156168 int64 time_elapsed = 0 ;
157169 uint64 loop_count = 0 ;
158- uint64 prev ,
159- cur ;
160170 instr_time start_time ,
161171 end_time ,
162- temp ;
172+ prev ,
173+ cur ;
174+ char * time_source = NULL ;
175+ bool fast_timing_available = false;
176+
177+ INSTR_TIME_INITIALIZE ();
178+
179+ #if !defined(WIN32 ) && defined(__x86_64__ ) && defined(__linux__ )
180+ if (fast_timing && has_rdtsc )
181+ {
182+ time_source = "RDTSC" ;
183+ fast_timing_available = true;
184+ }
185+ else if (has_rdtscp )
186+ time_source = "RDTSCP" ;
187+ else
188+ time_source = PG_INSTR_CLOCK_NAME ;
189+ #else
190+ time_source = PG_INSTR_CLOCK_NAME ;
191+ #endif
192+ if (fast_timing && !fast_timing_available )
193+ return 0 ;
194+
195+ printf (_ ("Time source: %s\n" ), time_source );
163196
164197 /*
165198 * Pre-zero the statistics data structures. They're already zero by
@@ -173,18 +206,23 @@ test_timing(unsigned int duration)
173206
174207 total_time = duration > 0 ? duration * INT64CONST (1000000000 ) : 0 ;
175208
176- INSTR_TIME_SET_CURRENT (start_time );
177- cur = INSTR_TIME_GET_NANOSEC (start_time );
209+ if (fast_timing )
210+ INSTR_TIME_SET_CURRENT_FAST (start_time );
211+ else
212+ INSTR_TIME_SET_CURRENT (start_time );
213+ cur = start_time ;
178214
179215 while (time_elapsed < total_time )
180216 {
181217 int32 diff ,
182218 bits ;
183219
184220 prev = cur ;
185- INSTR_TIME_SET_CURRENT (temp );
186- cur = INSTR_TIME_GET_NANOSEC (temp );
187- diff = cur - prev ;
221+ if (fast_timing )
222+ INSTR_TIME_SET_CURRENT_FAST (cur );
223+ else
224+ INSTR_TIME_SET_CURRENT (cur );
225+ diff = INSTR_TIME_DIFF_NANOSEC (cur , prev );
188226
189227 /* Did time go backwards? */
190228 if (unlikely (diff < 0 ))
@@ -217,11 +255,13 @@ test_timing(unsigned int duration)
217255 largest_diff_count ++ ;
218256
219257 loop_count ++ ;
220- INSTR_TIME_SUBTRACT (temp , start_time );
221- time_elapsed = INSTR_TIME_GET_NANOSEC (temp );
258+ time_elapsed = INSTR_TIME_DIFF_NANOSEC (cur , start_time );
222259 }
223260
224- INSTR_TIME_SET_CURRENT (end_time );
261+ if (fast_timing )
262+ INSTR_TIME_SET_CURRENT_FAST (end_time );
263+ else
264+ INSTR_TIME_SET_CURRENT (end_time );
225265
226266 INSTR_TIME_SUBTRACT (end_time , start_time );
227267
0 commit comments