summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/endian/test/benchmark.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/endian/test/benchmark.cpp')
-rw-r--r--src/boost/libs/endian/test/benchmark.cpp233
1 files changed, 233 insertions, 0 deletions
diff --git a/src/boost/libs/endian/test/benchmark.cpp b/src/boost/libs/endian/test/benchmark.cpp
new file mode 100644
index 000000000..5183b45be
--- /dev/null
+++ b/src/boost/libs/endian/test/benchmark.cpp
@@ -0,0 +1,233 @@
+// benchmark.cpp ---------------------------------------------------------------------//
+
+// Copyright Beman Dawes 2011
+
+// Distributed under the Boost Software License, Version 1.0.
+// http://www.boost.org/LICENSE_1_0.txt
+
+#ifndef _SCL_SECURE_NO_WARNINGS
+# define _SCL_SECURE_NO_WARNINGS
+#endif
+
+#ifndef _CRT_SECURE_NO_WARNINGS
+# define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include <cstdlib>
+#include <boost/endian/conversion.hpp>
+#include <boost/random.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/timer/timer.hpp>
+#include <iostream>
+#include <string>
+
+using namespace boost;
+using std::cout;
+using std::cerr;
+using std::endl;
+using std::vector;
+
+namespace
+{
+ std::string command_args;
+ long long n_cases;
+ int places = 2;
+ bool verbose (false);
+
+#ifndef BOOST_TWO_ARG
+ typedef int32_t (*timee_func)(int32_t);
+#else
+ typedef void (*timee_func)(int32_t, int32_t&);
+#endif
+
+ typedef boost::timer::nanosecond_type nanosecond_t;
+
+//--------------------------------------------------------------------------------------//
+
+ nanosecond_t benchmark(timee_func timee, const char* msg,
+ nanosecond_t overhead = 0)
+ // Returns: total cpu time (i.e. system time + user time)
+ {
+ if (verbose)
+ cout << "\nRunning benchmark..." << endl;
+ int64_t sum = 0;
+ boost::timer::cpu_times times;
+ nanosecond_t cpu_time;
+ boost::timer::auto_cpu_timer t(places);
+
+ for (long long i = n_cases; i; --i)
+ {
+# ifndef BOOST_TWO_ARG
+ sum += timee(static_cast<int32_t>(i)) ;
+# else
+ int32_t y;
+ timee(static_cast<int32_t>(i), y);
+ sum += y;
+# endif
+ }
+ t.stop();
+ times = t.elapsed();
+ cpu_time = (times.system + times.user) - overhead;
+ const long double sec = 1000000000.0L;
+ cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
+ cout.precision(places);
+ cout << msg << " " << cpu_time / sec << endl;
+
+ if (verbose)
+ {
+ t.report();
+ cout << " Benchmark complete\n"
+ " sum is " << sum << endl;
+ }
+ return cpu_time;
+ }
+
+ void process_command_line(int argc, char * argv[])
+ {
+ for (int a = 0; a < argc; ++a)
+ {
+ command_args += argv[a];
+ if (a != argc-1)
+ command_args += ' ';
+ }
+
+ cout << command_args << '\n';;
+
+ if (argc >=2)
+#ifndef _MSC_VER
+ n_cases = std::atoll(argv[1]);
+#else
+ n_cases = _atoi64(argv[1]);
+#endif
+
+ for (; argc > 2; ++argv, --argc)
+ {
+ if ( *(argv[2]+1) == 'p' )
+ places = atoi( argv[2]+2 );
+ else if ( *(argv[2]+1) == 'v' )
+ verbose = true;
+ else
+ {
+ cout << "Error - unknown option: " << argv[2] << "\n\n";
+ argc = -1;
+ break;
+ }
+ }
+
+ if (argc < 2)
+ {
+ cout << "Usage: benchmark n [Options]\n"
+ " The argument n specifies the number of test cases to run\n"
+ " Options:\n"
+ " -v Verbose messages\n"
+ " -p# Decimal places for times; default -p" << places << "\n";
+ return std::exit(1);
+ }
+ }
+
+ inline void inplace(int32_t& x)
+ {
+ x = (static_cast<uint32_t>(x) << 24)
+ | ((static_cast<uint32_t>(x) << 8) & 0x00ff0000)
+ | ((static_cast<uint32_t>(x) >> 8) & 0x0000ff00)
+ | (static_cast<uint32_t>(x) >> 24);
+ }
+
+ inline int32_t by_return(int32_t x)
+ {
+ return (static_cast<uint32_t>(x) << 24)
+ | ((static_cast<uint32_t>(x) << 8) & 0x00ff0000)
+ | ((static_cast<uint32_t>(x) >> 8) & 0x0000ff00)
+ | (static_cast<uint32_t>(x) >> 24);
+ }
+
+ inline int32_t by_return_intrinsic(int32_t x)
+ {
+ return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(static_cast<uint32_t>(x));
+ }
+
+ inline int32_t by_return_pyry(int32_t x)
+ {
+ uint32_t step16;
+ step16 = static_cast<uint32_t>(x) << 16 | static_cast<uint32_t>(x) >> 16;
+ return
+ ((static_cast<uint32_t>(step16) << 8) & 0xff00ff00)
+ | ((static_cast<uint32_t>(step16) >> 8) & 0x00ff00ff);
+ }
+
+ inline int32_t two_operand(int32_t x, int32_t& y)
+ {
+ return y = ((x << 24) & 0xff000000) | ((x << 8) & 0x00ff0000) | ((x >> 24) & 0x000000ff)
+ | ((x >> 8) & 0x0000ff00);
+ }
+
+ inline int32_t modify_noop(int32_t x)
+ {
+ int32_t v(x);
+ return v;
+ }
+
+ inline int32_t modify_inplace(int32_t x)
+ {
+ int32_t v(x);
+ inplace(v);
+ return v;
+ }
+
+ inline int32_t modify_by_return(int32_t x)
+ {
+ int32_t v(x);
+ return by_return(v);
+ }
+
+ inline int32_t modify_by_return_pyry(int32_t x)
+ {
+ int32_t v(x);
+ return by_return_pyry(v);
+ }
+
+ inline int32_t modify_by_return_intrinsic(int32_t x)
+ {
+ int32_t v(x);
+ return by_return_intrinsic(v);
+ }
+
+ inline void non_modify_assign(int32_t x, int32_t& y)
+ {
+ y = x;
+ }
+
+ inline void non_modify_two_operand(int32_t x, int32_t& y)
+ {
+ two_operand(x, y);
+ }
+
+ inline void non_modify_by_return(int32_t x, int32_t& y)
+ {
+ y = by_return(x);
+ }
+
+} // unnamed namespace
+
+//-------------------------------------- main() ---------------------------------------//
+
+int main(int argc, char * argv[])
+{
+ process_command_line(argc, argv);
+
+ nanosecond_t overhead;
+
+#ifndef BOOST_TWO_ARG
+ overhead = benchmark(modify_noop, "modify no-op");
+ benchmark(modify_inplace, "modify in place"/*, overhead*/);
+ benchmark(modify_by_return, "modify by return"/*, overhead*/);
+ benchmark(modify_by_return_pyry, "modify by return_pyry"/*, overhead*/);
+ benchmark(modify_by_return_intrinsic, "modify by return_intrinsic"/*, overhead*/);
+#else
+ overhead = benchmark(non_modify_assign, "non_modify_assign ");
+ benchmark(non_modify_two_operand, "non_modify_two_operand", overhead);
+ benchmark(non_modify_by_return, "non_modify_by_return ", overhead);
+#endif
+
+ return 0;
+}