Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / ACE / performance-tests / Misc / basic_perf.cpp
blobee66281846a7a13c4585269efefad99a699cc5cb
2 //=============================================================================
3 /**
4 * @file basic_perf.cpp
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
28 // w/Sun C++ 4.2.
29 static u_int iterations = 1000000;
30 Foo foo;
31 Foo_v foo_v;
33 inline
34 void
35 inline_func ()
37 DO_SOMETHING
41 ///////////////////////////////////////////////////////////////////////////////
42 ///////////////////////////////////////////////////////////////////////////////
43 // function per_iteration
44 ///////////////////////////////////////////////////////////////////////////////
45 ///////////////////////////////////////////////////////////////////////////////
46 // Given an elapsed time in nanoseconds, returns the time per iteration
47 // in microseconds.
48 static
49 inline
50 double
51 per_iteration (const ACE_hrtime_t elapsed /* nanoseconds */)
53 double ms_per_iteration = (double) ACE_CU64_TO_CU32 (elapsed) / 1000.0 /
54 (double) iterations;
56 // Don't print out "-0.000" or "-0.001" . . .
57 return -0.002 < ms_per_iteration && ms_per_iteration < 0.0
58 ? 0.0
59 : ms_per_iteration;
63 ///////////////////////////////////////////////////////////////////////////////
64 ///////////////////////////////////////////////////////////////////////////////
65 // class Basic_Test
66 ///////////////////////////////////////////////////////////////////////////////
67 ///////////////////////////////////////////////////////////////////////////////
68 class Basic_Test
70 public:
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);
81 protected:
82 ACE_hrtime_t elapsed_time_;
84 void start_timing ()
86 timer_.reset ();
87 timer_.start ();
90 void stop_timing ()
92 timer_.stop ();
93 timer_.elapsed_time (elapsed_time_);
96 private:
97 ACE_High_Res_Timer &timer_;
98 ACE_hrtime_t empty_iteration_time_;
100 // Require the timer reference.
101 Basic_Test ();
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)
110 : elapsed_time_ (0),
111 timer_ (timer),
112 empty_iteration_time_ (empty_iteration_time)
116 Basic_Test::~Basic_Test ()
120 double
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));
128 void
129 Basic_Test::print_iteration_time (const char *message)
131 ACE_DEBUG ((LM_INFO, " %-41s %8.3f\n",
132 message,
133 this->iteration_time ()));
137 ///////////////////////////////////////////////////////////////////////////////
138 ///////////////////////////////////////////////////////////////////////////////
139 // class Empty_Iteration_Test
140 ///////////////////////////////////////////////////////////////////////////////
141 ///////////////////////////////////////////////////////////////////////////////
142 class Empty_Iteration_Test : public Basic_Test
144 public:
145 Empty_Iteration_Test (ACE_High_Res_Timer &timer) : Basic_Test (timer, 0) {}
146 virtual ~Empty_Iteration_Test () {};
148 virtual void run ();
150 ACE_hrtime_t empty_iteration_time () const
152 return elapsed_time_;
155 private:
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 &);
164 void
165 Empty_Iteration_Test::run ()
167 this->start_timing ();
169 for (u_int i = 0; i < iterations; ++i)
171 DO_SOMETHING
174 this->stop_timing ();
178 ///////////////////////////////////////////////////////////////////////////////
179 ///////////////////////////////////////////////////////////////////////////////
180 // class Inline_Call_Test
181 ///////////////////////////////////////////////////////////////////////////////
182 ///////////////////////////////////////////////////////////////////////////////
183 class Inline_Call_Test : public Basic_Test
185 public:
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 () {};
191 virtual void run ();
193 private:
194 // Require the timer reference.
195 Inline_Call_Test ();
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 &);
202 void
203 Inline_Call_Test::run ()
205 this->start_timing ();
207 for (u_int i = 0; i < iterations; ++i)
208 inline_func ();
210 this->stop_timing ();
214 ///////////////////////////////////////////////////////////////////////////////
215 ///////////////////////////////////////////////////////////////////////////////
216 // class Noninline_Call_Test
217 ///////////////////////////////////////////////////////////////////////////////
218 ///////////////////////////////////////////////////////////////////////////////
219 class Noninline_Call_Test : public Basic_Test
221 public:
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 () {};
227 virtual void run ();
229 private:
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 &);
238 void
239 Noninline_Call_Test::run ()
241 this->start_timing ();
243 for (u_int i = 0; i < iterations; ++i)
244 func ();
246 this->stop_timing ();
250 ///////////////////////////////////////////////////////////////////////////////
251 ///////////////////////////////////////////////////////////////////////////////
252 // class Inline_Member_Call_Test
253 ///////////////////////////////////////////////////////////////////////////////
254 ///////////////////////////////////////////////////////////////////////////////
255 class Inline_Member_Call_Test : public Basic_Test
257 public:
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 () {};
263 virtual void run ();
265 private:
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 &);
274 void
275 Inline_Member_Call_Test::run ()
277 this->start_timing ();
279 for (u_int i = 0; i < iterations; ++i)
280 foo.inline_func ();
282 this->stop_timing ();
286 ///////////////////////////////////////////////////////////////////////////////
287 ///////////////////////////////////////////////////////////////////////////////
288 // class Noninline_Member_Call_Test
289 ///////////////////////////////////////////////////////////////////////////////
290 ///////////////////////////////////////////////////////////////////////////////
291 class Noninline_Member_Call_Test : public Basic_Test
293 public:
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 () {};
299 virtual void run ();
301 private:
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 &);
310 void
311 Noninline_Member_Call_Test::run ()
313 this->start_timing ();
315 for (u_int i = 0; i < iterations; ++i)
316 foo.func ();
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
329 public:
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 () {};
335 virtual void run ();
337 private:
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 &);
348 void
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
367 public:
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 () {};
373 virtual void run ();
375 private:
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 &);
386 void
387 Noninline_Member_With_Virtual_Call_Test::run ()
389 this->start_timing ();
391 for (u_int i = 0; i < iterations; ++i)
392 foo_v.func ();
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
405 public:
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 () {};
411 virtual void run ();
413 private:
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 &);
424 void
425 Virtual_Member_Optimizable_Call_Test::run ()
427 Foo_v &fv_o = foo_v;
429 this->start_timing ();
431 for (u_int i = 0; i < iterations; ++i)
432 fv_o.v_func ();
434 this->stop_timing ();
438 ///////////////////////////////////////////////////////////////////////////////
439 ///////////////////////////////////////////////////////////////////////////////
440 // class Virtual_Member_Call_Test
441 ///////////////////////////////////////////////////////////////////////////////
442 ///////////////////////////////////////////////////////////////////////////////
443 class Virtual_Member_Call_Test : public Basic_Test
445 public:
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 () {};
451 virtual void run ();
453 private:
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 &);
462 void
463 Virtual_Member_Call_Test::run ()
465 Foo_v *fv;
467 if (iterations < 2)
468 fv = new Foo_v;
469 else
470 fv = new Foo_d_v;
472 this->start_timing ();
474 for (u_int i = 0; i < iterations; ++i)
475 fv->v_func ();
477 this->stop_timing ();
479 delete fv;
480 fv = 0;
484 ///////////////////////////////////////////////////////////////////////////////
485 ///////////////////////////////////////////////////////////////////////////////
486 // function get_options
487 ///////////////////////////////////////////////////////////////////////////////
488 ///////////////////////////////////////////////////////////////////////////////
489 static
490 unsigned int
491 get_options (int argc, ACE_TCHAR *argv [])
493 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT("i:?"));
494 int opt;
496 while ((opt = get_opt ()) != EOF)
498 switch (opt)
500 case 'i':
502 int temp = ACE_OS::atoi (get_opt.opt_arg ());
503 if (temp > 0)
504 iterations = (u_int) temp;
505 else
507 ACE_DEBUG ((LM_ERROR, "%s: number of iterations must be > 0\n",
508 argv [0]));
509 return 1;
511 break;
513 case '?':
514 ACE_DEBUG ((LM_INFO, "usage: %s %s\n", argv [0], usage));
515 ACE_OS::exit (0);
516 break;
517 default:
518 ACE_DEBUG ((LM_ERROR, "%s: unknown arg, %c\n", argv [0],
519 (char) opt));
520 ACE_DEBUG ((LM_ERROR, "usage: %s %s\n", argv [0], usage));
521 return 1;
525 switch (argc - get_opt.opt_ind ())
527 case 0:
528 // OK
529 break;
530 default:
531 ACE_DEBUG ((LM_ERROR, "%s: too many arguments\n", argv [0]));
532 ACE_DEBUG ((LM_ERROR, "usage: %s %s\n", argv [0], usage));
533 return 1;
536 return 0;
540 ///////////////////////////////////////////////////////////////////////////////
541 ///////////////////////////////////////////////////////////////////////////////
542 // function main
543 ///////////////////////////////////////////////////////////////////////////////
544 ///////////////////////////////////////////////////////////////////////////////
547 ACE_TMAIN (int argc, ACE_TCHAR *argv[])
549 if (get_options (argc, argv))
550 ACE_OS::exit (-1);
552 ACE_utsname name;
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 "
622 "function:\n"));
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");
634 return 0;
638 // EOF