2 //=============================================================================
6 * Times various simple operations.
8 * With Sun C++, use -O2: make CFLAGS="-mt -O2" BIN=basic_perf
9 * -fast seems to produce slower times.
11 * @author David Levine
13 //=============================================================================
16 #include "basic_func.h"
17 #include "ace/High_Res_Timer.h"
18 #include "ace/Get_Opt.h"
19 #include "ace/OS_main.h"
20 #include "ace/Log_Msg.h"
21 #include "ace/OS_NS_stdlib.h"
22 #include "ace/OS_NS_sys_utsname.h"
24 static const char usage
[] = "[-? |\n"
25 " [-i <iterations> [1000000]]";
27 // These are global. They appear to bust the CPU cache, on an Ultra 2
29 static u_int iterations
= 1000000;
41 ///////////////////////////////////////////////////////////////////////////////
42 ///////////////////////////////////////////////////////////////////////////////
43 // function per_iteration
44 ///////////////////////////////////////////////////////////////////////////////
45 ///////////////////////////////////////////////////////////////////////////////
46 // Given an elapsed time in nanoseconds, returns the time per iteration
51 per_iteration (const ACE_hrtime_t elapsed
/* nanoseconds */)
53 double ms_per_iteration
= (double) ACE_CU64_TO_CU32 (elapsed
) / 1000.0 /
56 // Don't print out "-0.000" or "-0.001" . . .
57 return -0.002 < ms_per_iteration
&& ms_per_iteration
< 0.0
63 ///////////////////////////////////////////////////////////////////////////////
64 ///////////////////////////////////////////////////////////////////////////////
66 ///////////////////////////////////////////////////////////////////////////////
67 ///////////////////////////////////////////////////////////////////////////////
71 Basic_Test (ACE_High_Res_Timer
&timer
,
72 ACE_hrtime_t empty_iteration_time
);
73 virtual ~Basic_Test ();
75 virtual void run () = 0;
77 double iteration_time ();
79 void print_iteration_time (const char *message
);
82 ACE_hrtime_t elapsed_time_
;
93 timer_
.elapsed_time (elapsed_time_
);
97 ACE_High_Res_Timer
&timer_
;
98 ACE_hrtime_t empty_iteration_time_
;
100 // Require the timer reference.
103 // Force construction of independent instances by prohibiting copying.
104 Basic_Test (const Basic_Test
&);
105 Basic_Test
&operator= (const Basic_Test
&);
108 Basic_Test::Basic_Test (ACE_High_Res_Timer
&timer
,
109 ACE_hrtime_t empty_iteration_time
)
112 empty_iteration_time_ (empty_iteration_time
)
116 Basic_Test::~Basic_Test ()
121 Basic_Test::iteration_time ()
123 return per_iteration (elapsed_time_
> empty_iteration_time_
?
124 elapsed_time_
- empty_iteration_time_
:
125 static_cast<ACE_hrtime_t
> (0));
129 Basic_Test::print_iteration_time (const char *message
)
131 ACE_DEBUG ((LM_INFO
, " %-41s %8.3f\n",
133 this->iteration_time ()));
137 ///////////////////////////////////////////////////////////////////////////////
138 ///////////////////////////////////////////////////////////////////////////////
139 // class Empty_Iteration_Test
140 ///////////////////////////////////////////////////////////////////////////////
141 ///////////////////////////////////////////////////////////////////////////////
142 class Empty_Iteration_Test
: public Basic_Test
145 Empty_Iteration_Test (ACE_High_Res_Timer
&timer
) : Basic_Test (timer
, 0) {}
146 virtual ~Empty_Iteration_Test () {};
150 ACE_hrtime_t
empty_iteration_time () const
152 return elapsed_time_
;
156 // Require the timer reference.
157 Empty_Iteration_Test ();
159 // Force construction of independent instances by prohibiting copying.
160 Empty_Iteration_Test (const Empty_Iteration_Test
&);
161 Empty_Iteration_Test
&operator= (const Empty_Iteration_Test
&);
165 Empty_Iteration_Test::run ()
167 this->start_timing ();
169 for (u_int i
= 0; i
< iterations
; ++i
)
174 this->stop_timing ();
178 ///////////////////////////////////////////////////////////////////////////////
179 ///////////////////////////////////////////////////////////////////////////////
180 // class Inline_Call_Test
181 ///////////////////////////////////////////////////////////////////////////////
182 ///////////////////////////////////////////////////////////////////////////////
183 class Inline_Call_Test
: public Basic_Test
186 Inline_Call_Test (ACE_High_Res_Timer
&timer
,
187 ACE_hrtime_t empty_iteration_time
)
188 : Basic_Test (timer
, empty_iteration_time
) {}
189 virtual ~Inline_Call_Test () {};
194 // Require the timer reference.
197 // Force construction of independent instances by prohibiting copying.
198 Inline_Call_Test (const Inline_Call_Test
&);
199 Inline_Call_Test
&operator= (const Inline_Call_Test
&);
203 Inline_Call_Test::run ()
205 this->start_timing ();
207 for (u_int i
= 0; i
< iterations
; ++i
)
210 this->stop_timing ();
214 ///////////////////////////////////////////////////////////////////////////////
215 ///////////////////////////////////////////////////////////////////////////////
216 // class Noninline_Call_Test
217 ///////////////////////////////////////////////////////////////////////////////
218 ///////////////////////////////////////////////////////////////////////////////
219 class Noninline_Call_Test
: public Basic_Test
222 Noninline_Call_Test (ACE_High_Res_Timer
&timer
,
223 ACE_hrtime_t empty_iteration_time
)
224 : Basic_Test (timer
, empty_iteration_time
) {}
225 virtual ~Noninline_Call_Test () {};
230 // Require the timer reference.
231 Noninline_Call_Test ();
233 // Force construction of independent instances by prohibiting copying.
234 Noninline_Call_Test (const Noninline_Call_Test
&);
235 Noninline_Call_Test
&operator= (const Noninline_Call_Test
&);
239 Noninline_Call_Test::run ()
241 this->start_timing ();
243 for (u_int i
= 0; i
< iterations
; ++i
)
246 this->stop_timing ();
250 ///////////////////////////////////////////////////////////////////////////////
251 ///////////////////////////////////////////////////////////////////////////////
252 // class Inline_Member_Call_Test
253 ///////////////////////////////////////////////////////////////////////////////
254 ///////////////////////////////////////////////////////////////////////////////
255 class Inline_Member_Call_Test
: public Basic_Test
258 Inline_Member_Call_Test (ACE_High_Res_Timer
&timer
,
259 ACE_hrtime_t empty_iteration_time
)
260 : Basic_Test (timer
, empty_iteration_time
) {}
261 virtual ~Inline_Member_Call_Test () {};
266 // Require the timer reference.
267 Inline_Member_Call_Test ();
269 // Force construction of independent instances by prohibiting copying.
270 Inline_Member_Call_Test (const Inline_Member_Call_Test
&);
271 Inline_Member_Call_Test
&operator= (const Inline_Member_Call_Test
&);
275 Inline_Member_Call_Test::run ()
277 this->start_timing ();
279 for (u_int i
= 0; i
< iterations
; ++i
)
282 this->stop_timing ();
286 ///////////////////////////////////////////////////////////////////////////////
287 ///////////////////////////////////////////////////////////////////////////////
288 // class Noninline_Member_Call_Test
289 ///////////////////////////////////////////////////////////////////////////////
290 ///////////////////////////////////////////////////////////////////////////////
291 class Noninline_Member_Call_Test
: public Basic_Test
294 Noninline_Member_Call_Test (ACE_High_Res_Timer
&timer
,
295 ACE_hrtime_t empty_iteration_time
)
296 : Basic_Test (timer
, empty_iteration_time
) {}
297 virtual ~Noninline_Member_Call_Test () {};
302 // Require the timer reference.
303 Noninline_Member_Call_Test ();
305 // Force construction of independent instances by prohibiting copying.
306 Noninline_Member_Call_Test (const Noninline_Member_Call_Test
&);
307 Noninline_Member_Call_Test
&operator= (const Noninline_Member_Call_Test
&);
311 Noninline_Member_Call_Test::run ()
313 this->start_timing ();
315 for (u_int i
= 0; i
< iterations
; ++i
)
318 this->stop_timing ();
322 ///////////////////////////////////////////////////////////////////////////////
323 ///////////////////////////////////////////////////////////////////////////////
324 // class Inline_Member_With_Virtual_Call_Test
325 ///////////////////////////////////////////////////////////////////////////////
326 ///////////////////////////////////////////////////////////////////////////////
327 class Inline_Member_With_Virtual_Call_Test
: public Basic_Test
330 Inline_Member_With_Virtual_Call_Test (ACE_High_Res_Timer
&timer
,
331 ACE_hrtime_t empty_iteration_time
)
332 : Basic_Test (timer
, empty_iteration_time
) {}
333 virtual ~Inline_Member_With_Virtual_Call_Test () {};
338 // Require the timer reference.
339 Inline_Member_With_Virtual_Call_Test ();
341 // Force construction of independent instances by prohibiting copying.
342 Inline_Member_With_Virtual_Call_Test (
343 const Inline_Member_With_Virtual_Call_Test
&);
344 Inline_Member_With_Virtual_Call_Test
&operator= (
345 const Inline_Member_With_Virtual_Call_Test
&);
349 Inline_Member_With_Virtual_Call_Test::run ()
351 this->start_timing ();
353 for (u_int i
= 0; i
< iterations
; ++i
)
354 foo_v
.inline_func ();
356 this->stop_timing ();
360 ///////////////////////////////////////////////////////////////////////////////
361 ///////////////////////////////////////////////////////////////////////////////
362 // class Noninline_Member_With_Virtual_Call_Test
363 ///////////////////////////////////////////////////////////////////////////////
364 ///////////////////////////////////////////////////////////////////////////////
365 class Noninline_Member_With_Virtual_Call_Test
: public Basic_Test
368 Noninline_Member_With_Virtual_Call_Test (ACE_High_Res_Timer
&timer
,
369 ACE_hrtime_t empty_iteration_time
)
370 : Basic_Test (timer
, empty_iteration_time
) {}
371 virtual ~Noninline_Member_With_Virtual_Call_Test () {};
376 // Require the timer reference.
377 Noninline_Member_With_Virtual_Call_Test ();
379 // Force construction of independent instances by prohibiting copying.
380 Noninline_Member_With_Virtual_Call_Test
381 (const Noninline_Member_With_Virtual_Call_Test
&);
382 Noninline_Member_With_Virtual_Call_Test
&operator=
383 (const Noninline_Member_With_Virtual_Call_Test
&);
387 Noninline_Member_With_Virtual_Call_Test::run ()
389 this->start_timing ();
391 for (u_int i
= 0; i
< iterations
; ++i
)
394 this->stop_timing ();
398 ///////////////////////////////////////////////////////////////////////////////
399 ///////////////////////////////////////////////////////////////////////////////
400 // class Virtual_Member_Optimizable_Call_Test
401 ///////////////////////////////////////////////////////////////////////////////
402 ///////////////////////////////////////////////////////////////////////////////
403 class Virtual_Member_Optimizable_Call_Test
: public Basic_Test
406 Virtual_Member_Optimizable_Call_Test (ACE_High_Res_Timer
&timer
,
407 ACE_hrtime_t empty_iteration_time
)
408 : Basic_Test (timer
, empty_iteration_time
) {}
409 virtual ~Virtual_Member_Optimizable_Call_Test () {};
414 // Require the timer reference.
415 Virtual_Member_Optimizable_Call_Test ();
417 // Force construction of independent instances by prohibiting copying.
418 Virtual_Member_Optimizable_Call_Test (
419 const Virtual_Member_Optimizable_Call_Test
&);
420 Virtual_Member_Optimizable_Call_Test
&operator= (
421 const Virtual_Member_Optimizable_Call_Test
&);
425 Virtual_Member_Optimizable_Call_Test::run ()
429 this->start_timing ();
431 for (u_int i
= 0; i
< iterations
; ++i
)
434 this->stop_timing ();
438 ///////////////////////////////////////////////////////////////////////////////
439 ///////////////////////////////////////////////////////////////////////////////
440 // class Virtual_Member_Call_Test
441 ///////////////////////////////////////////////////////////////////////////////
442 ///////////////////////////////////////////////////////////////////////////////
443 class Virtual_Member_Call_Test
: public Basic_Test
446 Virtual_Member_Call_Test (ACE_High_Res_Timer
&timer
,
447 ACE_hrtime_t empty_iteration_time
)
448 : Basic_Test (timer
, empty_iteration_time
) {}
449 virtual ~Virtual_Member_Call_Test () {};
454 // Require the timer reference.
455 Virtual_Member_Call_Test ();
457 // Force construction of independent instances by prohibiting copying.
458 Virtual_Member_Call_Test (const Virtual_Member_Call_Test
&);
459 Virtual_Member_Call_Test
&operator= (const Virtual_Member_Call_Test
&);
463 Virtual_Member_Call_Test::run ()
472 this->start_timing ();
474 for (u_int i
= 0; i
< iterations
; ++i
)
477 this->stop_timing ();
484 ///////////////////////////////////////////////////////////////////////////////
485 ///////////////////////////////////////////////////////////////////////////////
486 // function get_options
487 ///////////////////////////////////////////////////////////////////////////////
488 ///////////////////////////////////////////////////////////////////////////////
491 get_options (int argc
, ACE_TCHAR
*argv
[])
493 ACE_Get_Opt
get_opt (argc
, argv
, ACE_TEXT("i:?"));
496 while ((opt
= get_opt ()) != EOF
)
502 int temp
= ACE_OS::atoi (get_opt
.opt_arg ());
504 iterations
= (u_int
) temp
;
507 ACE_DEBUG ((LM_ERROR
, "%s: number of iterations must be > 0\n",
514 ACE_DEBUG ((LM_INFO
, "usage: %s %s\n", argv
[0], usage
));
518 ACE_DEBUG ((LM_ERROR
, "%s: unknown arg, %c\n", argv
[0],
520 ACE_DEBUG ((LM_ERROR
, "usage: %s %s\n", argv
[0], usage
));
525 switch (argc
- get_opt
.opt_ind ())
531 ACE_DEBUG ((LM_ERROR
, "%s: too many arguments\n", argv
[0]));
532 ACE_DEBUG ((LM_ERROR
, "usage: %s %s\n", argv
[0], usage
));
540 ///////////////////////////////////////////////////////////////////////////////
541 ///////////////////////////////////////////////////////////////////////////////
543 ///////////////////////////////////////////////////////////////////////////////
544 ///////////////////////////////////////////////////////////////////////////////
547 ACE_TMAIN (int argc
, ACE_TCHAR
*argv
[])
549 if (get_options (argc
, argv
))
554 if (ACE_OS::uname (&name
) != -1)
555 ACE_DEBUG ((LM_INFO
, "%s (%s), %s %s at %T\n",
556 name
.nodename
, name
.machine
, name
.sysname
, name
.release
));
558 ACE_DEBUG ((LM_INFO
, "%u iterations\n", iterations
));
561 // Use one timer for all the tests. No particular reason why.
562 ACE_High_Res_Timer timer
;
564 // Calculate the time for an "empty iteration", and subtract it
565 // from each test time.
566 ACE_hrtime_t iteration_time
;
568 Empty_Iteration_Test
empty_iteration_test (timer
);
569 empty_iteration_test
.run ();
570 ACE_DEBUG ((LM_INFO
, "An empty iteration costs %8.3f microseconds.\n\n",
571 empty_iteration_test
.iteration_time ()));
572 iteration_time
= empty_iteration_test
.empty_iteration_time ();
575 // Run the real tests . . .
576 Inline_Call_Test
inline_call_test (timer
, iteration_time
);
577 inline_call_test
.run ();
579 Noninline_Call_Test
noninline_call_test (timer
, iteration_time
);
580 noninline_call_test
.run ();
582 Inline_Member_Call_Test
inline_member_call_test (timer
, iteration_time
);
583 inline_member_call_test
.run ();
585 Noninline_Member_Call_Test
noninline_member_call_test (
586 timer
, iteration_time
);
587 noninline_member_call_test
.run ();
589 Inline_Member_With_Virtual_Call_Test
590 inline_member_with_virtual_call_test (timer
, iteration_time
);
591 inline_member_with_virtual_call_test
.run ();
593 Noninline_Member_With_Virtual_Call_Test
594 noninline_member_with_virtual_call_test (timer
, iteration_time
);
595 noninline_member_with_virtual_call_test
.run ();
597 Virtual_Member_Optimizable_Call_Test
598 virtual_member_optimizable_call_test (timer
, iteration_time
);
599 virtual_member_optimizable_call_test
.run ();
601 Virtual_Member_Call_Test
virtual_member_call_test (timer
, iteration_time
);
602 virtual_member_call_test
.run ();
605 // Print results . . .
606 ACE_DEBUG ((LM_INFO
, "operation "
607 "time, microseconds\n"));
608 ACE_DEBUG ((LM_INFO
, "========= "
609 "=================="));
611 ACE_DEBUG ((LM_INFO
, "\nglobal function calls:\n"));
612 inline_call_test
.print_iteration_time ("inline function call");
613 noninline_call_test
.print_iteration_time ("non-inline function call");
615 ACE_DEBUG ((LM_INFO
, "\nmember function calls:\n"));
616 inline_member_call_test
.print_iteration_time (
617 "inline member function call");
618 noninline_member_call_test
.print_iteration_time (
619 "non-inline member function call");
621 ACE_DEBUG ((LM_INFO
, "\nmember function calls, class has a virtual "
623 inline_member_with_virtual_call_test
.print_iteration_time (
624 "inline member function with virtual call");
625 noninline_member_with_virtual_call_test
.print_iteration_time (
626 "non-inline member function w/virtual call");
628 ACE_DEBUG ((LM_INFO
, "\nvirtual member function calls:\n"));
629 virtual_member_optimizable_call_test
.print_iteration_time (
630 "virtual member function call, optimizable");
631 virtual_member_call_test
.print_iteration_time (
632 "virtual member function call");