summaryrefslogtreecommitdiff
path: root/ACE/performance-tests/Misc/basic_perf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/performance-tests/Misc/basic_perf.cpp')
-rw-r--r--ACE/performance-tests/Misc/basic_perf.cpp646
1 files changed, 646 insertions, 0 deletions
diff --git a/ACE/performance-tests/Misc/basic_perf.cpp b/ACE/performance-tests/Misc/basic_perf.cpp
new file mode 100644
index 00000000000..d084e84e1b2
--- /dev/null
+++ b/ACE/performance-tests/Misc/basic_perf.cpp
@@ -0,0 +1,646 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// performance-tests/Misc
+//
+// = FILENAME
+// basic_perf.cpp
+//
+// = DESCRIPTION
+// Times various simple operations.
+//
+// With Sun C++, use -O2: make CFLAGS="-mt -O2" BIN=basic_perf
+// -fast seems to produce slower times.
+//
+// = AUTHOR
+// David Levine
+//
+// ============================================================================
+
+#include "basic_func.h"
+#include "ace/High_Res_Timer.h"
+#include "ace/Get_Opt.h"
+#include "ace/OS_main.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_stdlib.h"
+#include "ace/OS_NS_sys_utsname.h"
+
+ACE_RCSID(Misc, basic_perf, "$Id$")
+
+static const char usage [] = "[-? |\n"
+ " [-i <iterations> [1000000]]";
+
+// These are global. They appear to bust the CPU cache, on an Ultra 2
+// w/Sun C++ 4.2.
+static u_int iterations = 1000000;
+Foo foo;
+Foo_v foo_v;
+
+inline
+void
+inline_func ()
+{
+ DO_SOMETHING
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// function per_iteration
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// Given an elapsed time in nanoseconds, returns the time per iteration
+// in microseconds.
+static
+inline
+double
+per_iteration (const ACE_hrtime_t elapsed /* nanoseconds */)
+{
+ double ms_per_iteration = (double) ACE_CU64_TO_CU32 (elapsed) / 1000.0 /
+ (double) iterations;
+
+ // Don't print out "-0.000" or "-0.001" . . .
+ return -0.002 < ms_per_iteration && ms_per_iteration < 0.0
+ ? 0.0
+ : ms_per_iteration;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// class Basic_Test
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+class Basic_Test
+{
+public:
+ Basic_Test (ACE_High_Res_Timer &timer,
+ ACE_hrtime_t empty_iteration_time);
+ virtual ~Basic_Test (void);
+
+ virtual void run (void) = 0;
+
+ double iteration_time (void);
+
+ void print_iteration_time (const char *message);
+
+protected:
+ ACE_hrtime_t elapsed_time_;
+
+ void start_timing (void)
+ {
+ timer_.reset ();
+ timer_.start ();
+ }
+
+ void stop_timing (void)
+ {
+ timer_.stop ();
+ timer_.elapsed_time (elapsed_time_);
+ }
+
+private:
+ ACE_High_Res_Timer &timer_;
+ ACE_hrtime_t empty_iteration_time_;
+
+ // Require the timer reference.
+ Basic_Test (void);
+
+ // Force construction of independent instances by prohibiting copying.
+ Basic_Test (const Basic_Test &);
+ Basic_Test &operator= (const Basic_Test &);
+};
+
+Basic_Test::Basic_Test (ACE_High_Res_Timer &timer,
+ ACE_hrtime_t empty_iteration_time)
+ : elapsed_time_ (0),
+ timer_ (timer),
+ empty_iteration_time_ (empty_iteration_time)
+{
+}
+
+Basic_Test::~Basic_Test (void)
+{
+}
+
+double
+Basic_Test::iteration_time (void)
+{
+ return per_iteration (elapsed_time_ > empty_iteration_time_ ?
+ elapsed_time_ - empty_iteration_time_ :
+ static_cast<ACE_hrtime_t> (0));
+}
+
+void
+Basic_Test::print_iteration_time (const char *message)
+{
+ ACE_DEBUG ((LM_INFO, " %-41s %8.3f\n",
+ message,
+ this->iteration_time ()));
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// class Empty_Iteration_Test
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+class Empty_Iteration_Test : public Basic_Test
+{
+public:
+ Empty_Iteration_Test (ACE_High_Res_Timer &timer) : Basic_Test (timer, 0) {}
+ virtual ~Empty_Iteration_Test (void) {};
+
+ virtual void run (void);
+
+ ACE_hrtime_t empty_iteration_time (void) const
+ {
+ return elapsed_time_;
+ }
+
+private:
+ // Require the timer reference.
+ Empty_Iteration_Test (void);
+
+ // Force construction of independent instances by prohibiting copying.
+ Empty_Iteration_Test (const Empty_Iteration_Test &);
+ Empty_Iteration_Test &operator= (const Empty_Iteration_Test &);
+};
+
+void
+Empty_Iteration_Test::run (void)
+{
+ this->start_timing ();
+
+ for (u_int i = 0; i < iterations; ++i)
+ {
+ DO_SOMETHING
+ }
+
+ this->stop_timing ();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// class Inline_Call_Test
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+class Inline_Call_Test : public Basic_Test
+{
+public:
+ Inline_Call_Test (ACE_High_Res_Timer &timer,
+ ACE_hrtime_t empty_iteration_time)
+ : Basic_Test (timer, empty_iteration_time) {}
+ virtual ~Inline_Call_Test (void) {};
+
+ virtual void run (void);
+
+private:
+ // Require the timer reference.
+ Inline_Call_Test (void);
+
+ // Force construction of independent instances by prohibiting copying.
+ Inline_Call_Test (const Inline_Call_Test &);
+ Inline_Call_Test &operator= (const Inline_Call_Test &);
+};
+
+void
+Inline_Call_Test::run (void)
+{
+ this->start_timing ();
+
+ for (u_int i = 0; i < iterations; ++i)
+ inline_func ();
+
+ this->stop_timing ();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// class Noninline_Call_Test
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+class Noninline_Call_Test : public Basic_Test
+{
+public:
+ Noninline_Call_Test (ACE_High_Res_Timer &timer,
+ ACE_hrtime_t empty_iteration_time)
+ : Basic_Test (timer, empty_iteration_time) {}
+ virtual ~Noninline_Call_Test (void) {};
+
+ virtual void run (void);
+
+private:
+ // Require the timer reference.
+ Noninline_Call_Test (void);
+
+ // Force construction of independent instances by prohibiting copying.
+ Noninline_Call_Test (const Noninline_Call_Test &);
+ Noninline_Call_Test &operator= (const Noninline_Call_Test &);
+};
+
+void
+Noninline_Call_Test::run (void)
+{
+ this->start_timing ();
+
+ for (u_int i = 0; i < iterations; ++i)
+ func ();
+
+ this->stop_timing ();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// class Inline_Member_Call_Test
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+class Inline_Member_Call_Test : public Basic_Test
+{
+public:
+ Inline_Member_Call_Test (ACE_High_Res_Timer &timer,
+ ACE_hrtime_t empty_iteration_time)
+ : Basic_Test (timer, empty_iteration_time) {}
+ virtual ~Inline_Member_Call_Test (void) {};
+
+ virtual void run (void);
+
+private:
+ // Require the timer reference.
+ Inline_Member_Call_Test (void);
+
+ // Force construction of independent instances by prohibiting copying.
+ Inline_Member_Call_Test (const Inline_Member_Call_Test &);
+ Inline_Member_Call_Test &operator= (const Inline_Member_Call_Test &);
+};
+
+void
+Inline_Member_Call_Test::run (void)
+{
+ this->start_timing ();
+
+ for (u_int i = 0; i < iterations; ++i)
+ foo.inline_func ();
+
+ this->stop_timing ();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// class Noninline_Member_Call_Test
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+class Noninline_Member_Call_Test : public Basic_Test
+{
+public:
+ Noninline_Member_Call_Test (ACE_High_Res_Timer &timer,
+ ACE_hrtime_t empty_iteration_time)
+ : Basic_Test (timer, empty_iteration_time) {}
+ virtual ~Noninline_Member_Call_Test (void) {};
+
+ virtual void run (void);
+
+private:
+ // Require the timer reference.
+ Noninline_Member_Call_Test (void);
+
+ // Force construction of independent instances by prohibiting copying.
+ Noninline_Member_Call_Test (const Noninline_Member_Call_Test &);
+ Noninline_Member_Call_Test &operator= (const Noninline_Member_Call_Test &);
+};
+
+void
+Noninline_Member_Call_Test::run (void)
+{
+ this->start_timing ();
+
+ for (u_int i = 0; i < iterations; ++i)
+ foo.func ();
+
+ this->stop_timing ();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// class Inline_Member_With_Virtual_Call_Test
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+class Inline_Member_With_Virtual_Call_Test : public Basic_Test
+{
+public:
+ Inline_Member_With_Virtual_Call_Test (ACE_High_Res_Timer &timer,
+ ACE_hrtime_t empty_iteration_time)
+ : Basic_Test (timer, empty_iteration_time) {}
+ virtual ~Inline_Member_With_Virtual_Call_Test (void) {};
+
+ virtual void run (void);
+
+private:
+ // Require the timer reference.
+ Inline_Member_With_Virtual_Call_Test (void);
+
+ // Force construction of independent instances by prohibiting copying.
+ Inline_Member_With_Virtual_Call_Test (
+ const Inline_Member_With_Virtual_Call_Test &);
+ Inline_Member_With_Virtual_Call_Test &operator= (
+ const Inline_Member_With_Virtual_Call_Test &);
+};
+
+void
+Inline_Member_With_Virtual_Call_Test::run (void)
+{
+ this->start_timing ();
+
+ for (u_int i = 0; i < iterations; ++i)
+ foo_v.inline_func ();
+
+ this->stop_timing ();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// class Noninline_Member_With_Virtual_Call_Test
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+class Noninline_Member_With_Virtual_Call_Test : public Basic_Test
+{
+public:
+ Noninline_Member_With_Virtual_Call_Test (ACE_High_Res_Timer &timer,
+ ACE_hrtime_t empty_iteration_time)
+ : Basic_Test (timer, empty_iteration_time) {}
+ virtual ~Noninline_Member_With_Virtual_Call_Test (void) {};
+
+ virtual void run (void);
+
+private:
+ // Require the timer reference.
+ Noninline_Member_With_Virtual_Call_Test (void);
+
+ // Force construction of independent instances by prohibiting copying.
+ Noninline_Member_With_Virtual_Call_Test
+ (const Noninline_Member_With_Virtual_Call_Test &);
+ Noninline_Member_With_Virtual_Call_Test &operator=
+ (const Noninline_Member_With_Virtual_Call_Test &);
+};
+
+void
+Noninline_Member_With_Virtual_Call_Test::run (void)
+{
+ this->start_timing ();
+
+ for (u_int i = 0; i < iterations; ++i)
+ foo_v.func ();
+
+ this->stop_timing ();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// class Virtual_Member_Optimizable_Call_Test
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+class Virtual_Member_Optimizable_Call_Test : public Basic_Test
+{
+public:
+ Virtual_Member_Optimizable_Call_Test (ACE_High_Res_Timer &timer,
+ ACE_hrtime_t empty_iteration_time)
+ : Basic_Test (timer, empty_iteration_time) {}
+ virtual ~Virtual_Member_Optimizable_Call_Test (void) {};
+
+ virtual void run (void);
+
+private:
+ // Require the timer reference.
+ Virtual_Member_Optimizable_Call_Test (void);
+
+ // Force construction of independent instances by prohibiting copying.
+ Virtual_Member_Optimizable_Call_Test (
+ const Virtual_Member_Optimizable_Call_Test &);
+ Virtual_Member_Optimizable_Call_Test &operator= (
+ const Virtual_Member_Optimizable_Call_Test &);
+};
+
+void
+Virtual_Member_Optimizable_Call_Test::run (void)
+{
+ Foo_v &fv_o = foo_v;
+
+ this->start_timing ();
+
+ for (u_int i = 0; i < iterations; ++i)
+ fv_o.v_func ();
+
+ this->stop_timing ();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// class Virtual_Member_Call_Test
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+class Virtual_Member_Call_Test : public Basic_Test
+{
+public:
+ Virtual_Member_Call_Test (ACE_High_Res_Timer &timer,
+ ACE_hrtime_t empty_iteration_time)
+ : Basic_Test (timer, empty_iteration_time) {}
+ virtual ~Virtual_Member_Call_Test (void) {};
+
+ virtual void run (void);
+
+private:
+ // Require the timer reference.
+ Virtual_Member_Call_Test (void);
+
+ // Force construction of independent instances by prohibiting copying.
+ Virtual_Member_Call_Test (const Virtual_Member_Call_Test &);
+ Virtual_Member_Call_Test &operator= (const Virtual_Member_Call_Test &);
+};
+
+void
+Virtual_Member_Call_Test::run (void)
+{
+ Foo_v *fv;
+
+ if (iterations < 2)
+ fv = new Foo_v;
+ else
+ fv = new Foo_d_v;
+
+ this->start_timing ();
+
+ for (u_int i = 0; i < iterations; ++i)
+ fv->v_func ();
+
+ this->stop_timing ();
+
+ delete fv;
+ fv = 0;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// function get_options
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+static
+unsigned int
+get_options (int argc, ACE_TCHAR *argv [])
+{
+ ACE_Get_Opt get_opt (argc, argv, ACE_TEXT("i:?"));
+ int opt;
+
+ while ((opt = get_opt ()) != EOF)
+ {
+ switch (opt)
+ {
+ case 'i':
+ {
+ int temp = ACE_OS::atoi (get_opt.opt_arg ());
+ if (temp > 0)
+ iterations = (u_int) temp;
+ else
+ {
+ ACE_DEBUG ((LM_ERROR, "%s: number of iterations must be > 0\n",
+ argv [0]));
+ return 1;
+ }
+ break;
+ }
+ case '?':
+ ACE_DEBUG ((LM_INFO, "usage: %s %s\n", argv [0], usage));
+ ACE_OS::exit (0);
+ break;
+ default:
+ ACE_DEBUG ((LM_ERROR, "%s: unknown arg, %c\n", argv [0],
+ (char) opt));
+ ACE_DEBUG ((LM_ERROR, "usage: %s %s\n", argv [0], usage));
+ return 1;
+ }
+ }
+
+ switch (argc - get_opt.opt_ind ())
+ {
+ case 0:
+ // OK
+ break;
+ default:
+ ACE_DEBUG ((LM_ERROR, "%s: too many arguments\n", argv [0]));
+ ACE_DEBUG ((LM_ERROR, "usage: %s %s\n", argv [0], usage));
+ return 1;
+ }
+
+ return 0;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// function main
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ if (get_options (argc, argv))
+ ACE_OS::exit (-1);
+
+ ACE_utsname name;
+
+ if (ACE_OS::uname (&name) != -1)
+ ACE_DEBUG ((LM_INFO, "%s (%s), %s %s at %T\n",
+ name.nodename, name.machine, name.sysname, name.release));
+
+ ACE_DEBUG ((LM_INFO, "%u iterations\n", iterations));
+
+
+ // Use one timer for all the tests. No particular reason why.
+ ACE_High_Res_Timer timer;
+
+ // Calculate the time for an "empty iteration", and subtract it
+ // from each test time.
+ ACE_hrtime_t iteration_time;
+
+ Empty_Iteration_Test empty_iteration_test (timer);
+ empty_iteration_test.run ();
+ ACE_DEBUG ((LM_INFO, "An empty iteration costs %8.3f microseconds.\n\n",
+ empty_iteration_test.iteration_time ()));
+ iteration_time = empty_iteration_test.empty_iteration_time ();
+
+
+ // Run the real tests . . .
+ Inline_Call_Test inline_call_test (timer, iteration_time);
+ inline_call_test.run ();
+
+ Noninline_Call_Test noninline_call_test (timer, iteration_time);
+ noninline_call_test.run ();
+
+ Inline_Member_Call_Test inline_member_call_test (timer, iteration_time);
+ inline_member_call_test.run ();
+
+ Noninline_Member_Call_Test noninline_member_call_test (
+ timer, iteration_time);
+ noninline_member_call_test.run ();
+
+ Inline_Member_With_Virtual_Call_Test
+ inline_member_with_virtual_call_test (timer, iteration_time);
+ inline_member_with_virtual_call_test.run ();
+
+ Noninline_Member_With_Virtual_Call_Test
+ noninline_member_with_virtual_call_test (timer, iteration_time);
+ noninline_member_with_virtual_call_test.run ();
+
+ Virtual_Member_Optimizable_Call_Test
+ virtual_member_optimizable_call_test (timer, iteration_time);
+ virtual_member_optimizable_call_test.run ();
+
+ Virtual_Member_Call_Test virtual_member_call_test (timer, iteration_time);
+ virtual_member_call_test.run ();
+
+
+ // Print results . . .
+ ACE_DEBUG ((LM_INFO, "operation "
+ "time, microseconds\n"));
+ ACE_DEBUG ((LM_INFO, "========= "
+ "=================="));
+
+ ACE_DEBUG ((LM_INFO, "\nglobal function calls:\n"));
+ inline_call_test.print_iteration_time ("inline function call");
+ noninline_call_test.print_iteration_time ("non-inline function call");
+
+ ACE_DEBUG ((LM_INFO, "\nmember function calls:\n"));
+ inline_member_call_test.print_iteration_time (
+ "inline member function call");
+ noninline_member_call_test.print_iteration_time (
+ "non-inline member function call");
+
+ ACE_DEBUG ((LM_INFO, "\nmember function calls, class has a virtual "
+ "function:\n"));
+ inline_member_with_virtual_call_test.print_iteration_time (
+ "inline member function with virtual call");
+ noninline_member_with_virtual_call_test.print_iteration_time (
+ "non-inline member function w/virtual call");
+
+ ACE_DEBUG ((LM_INFO, "\nvirtual member function calls:\n"));
+ virtual_member_optimizable_call_test.print_iteration_time (
+ "virtual member function call, optimizable");
+ virtual_member_call_test.print_iteration_time (
+ "virtual member function call");
+
+ return 0;
+}
+
+
+// EOF