123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- // 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;
- }
|