diff options
Diffstat (limited to 'src/boost/libs/endian/test/benchmark.cpp')
-rw-r--r-- | src/boost/libs/endian/test/benchmark.cpp | 233 |
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 00000000..5183b45b --- /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; +} |