diff --git a/test/benchmark.cpp b/test/benchmark.cpp
index cd09ff1..e7f1f8e 100644
--- a/test/benchmark.cpp
+++ b/test/benchmark.cpp
@@ -35,9 +35,12 @@ namespace
#endif
typedef boost::timer::nanosecond_type nanosecond_t;
+
+//--------------------------------------------------------------------------------------//
nanosecond_t benchmark(timee_func timee, const char* msg,
- nanosecond_t overhead = 0)
+ nanosecond_t overhead = 0)
+ // Returns: total cpu time (i.e. system time + user time)
{
if (verbose)
cout << "\nRunning benchmark..." << endl;
diff --git a/test/msvc2012/speed_test/speed_test.vcxproj b/test/msvc2012/speed_test/speed_test.vcxproj
index 3ee2b16..d19c9a1 100644
--- a/test/msvc2012/speed_test/speed_test.vcxproj
+++ b/test/msvc2012/speed_test/speed_test.vcxproj
@@ -59,6 +59,9 @@
Console
true
+
+ "$(TargetDir)\$(TargetName).exe" 10000000
+
@@ -76,6 +79,9 @@
true
true
+
+ "$(TargetDir)\$(TargetName).exe" 1000000000
+
diff --git a/test/speed_test.cpp b/test/speed_test.cpp
index 67f11ce..5bcde9d 100644
--- a/test/speed_test.cpp
+++ b/test/speed_test.cpp
@@ -11,78 +11,165 @@
#include
#include
-#include
#include
+#include
#include
#include
#include
+using namespace boost;
using namespace boost::endian;
-using namespace boost::chrono;
using std::cout;
using std::endl;
-using boost::int16_t;
-using boost::uint16_t;
-using boost::int32_t;
-using boost::uint32_t;
-using boost::int64_t;
-using boost::uint64_t;
namespace
{
- long default_length(1);
- steady_clock::duration length = seconds(default_length);
+ typedef boost::timer::nanosecond_type nanosecond_t;
+ std::string command_args;
+ uint64_t n; // number of test cases to run
+ int places = 3; // decimal places for times
+ bool verbose (false);
- template
- uint32_t test(T x)
+ struct result_type
{
- uint32_t count = 0;
- T y = x;
- steady_clock::time_point start = steady_clock::now();
- steady_clock::time_point end = start + length;
- while (steady_clock::now() < end)
+ nanosecond_t cpu_time; // system + user time
+ uint64_t v; // value computed; returning this may prevent
+ // optimizer from optimizing away the timing loop
+ };
+
+ 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 = std::atoll(argv[1]);
+#else
+ n = _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);
+ }
+ }
+
+//--------------------------------------------------------------------------------------//
+
+ template
+ result_type test_inc(T x)
+ {
+ cout << "++ a value..." << endl;
+ result_type result;
+ result.v = 0;
+ T y(x);
+ boost::timer::auto_cpu_timer t(places);
+ for (uint64_t i = 0; i < n; ++i)
+ {
+ ++y;
+ }
+ t.stop();
+ result.v = static_cast(y);
+ boost::timer::cpu_times times = t.elapsed();
+ result.cpu_time = (times.system + times.user);
+ t.report();
+ return result;
+ }
+
+ template
+ result_type test_rev_inc(T x)
+ {
+ cout << "reverse, then ++ a value..." << endl;
+ result_type result;
+ result.v = 0;
+ T y(x);
+ boost::timer::auto_cpu_timer t(places);
+ for (uint64_t i = 0; i < n; ++i)
{
- ++count;
reverse(y);
++y;
reverse(y);
}
-
- cout << " loop executed " << count << " times" << endl;
-// cout << " x is 0x" << std::hex << x << std::dec << endl;
-
- count = 0;
- //Endian z(x);
- Endian z;
- start = steady_clock::now();
- end = start + length;
- while (steady_clock::now() < end)
- {
- ++count;
- ++z;
- }
-
- cout << " loop executed " << count << " times" << endl;
-
- return count;
+ t.stop();
+ result.v = static_cast(y);
+ boost::timer::cpu_times times = t.elapsed();
+ result.cpu_time = (times.system + times.user);
+ t.report();
+ return result;
}
- uint32_t nop_test()
+ template
+ result_type test_endian_inc(T x)
{
- uint32_t count = 0;
- steady_clock::time_point start = steady_clock::now();
- steady_clock::time_point end = start + length;
- while (steady_clock::now() < end)
+ cout << "++ an endian value..." << endl;
+ result_type result;
+ result.v = 0;
+ EndianT y(x);
+ boost::timer::auto_cpu_timer t(places);
+ for (uint64_t i = 0; i < n; ++i)
{
- ++count;
+ ++y;
}
-
- cout << " loop executed " << count << " times" << endl;
-
- return count;
+ t.stop();
+ result.v = static_cast(y);
+ boost::timer::cpu_times times = t.elapsed();
+ result.cpu_time = (times.system + times.user);
+ t.report();
+ return result;
}
+ template
+ void test(T x)
+ {
+ test_inc(x);
+ test_rev_inc(x);
+ test_endian_inc(x);
+ }
+
+
+ //result_type nop_test()
+ //{
+ // result_type result;
+ // result.v = 0;
+ // boost::timer::auto_cpu_timer t(places);
+ // for (uint64_t i = 0; i < n; ++i)
+ // {
+ // ++result.v;
+ // }
+ // t.stop();
+ // boost::timer::cpu_times times = t.elapsed();
+ // result.cpu_time = (times.system + times.user);
+ // t.report();
+ // return result;
+ //}
+
} // unnamed namespace
@@ -90,40 +177,27 @@ namespace
int cpp_main(int argc, char* argv[])
{
- if (argc > 1)
- length = seconds(atol(argv[1]));
- else
- {
- cout << "Invoke: speed_test [s]\n"
- " where s is the number of seconds each test will be run (default "
- << default_length << (default_length <= 1 ? " second)" : " seconds)") << endl;
- }
+ process_command_line(argc, argv);
- cout << "\nbyte swap intrinsics used: " BOOST_ENDIAN_INTRINSIC_MSG << endl << endl;
-
- //std::cerr << std::hex;
+ cout << "\nbyte swap intrinsics used: " BOOST_ENDIAN_INTRINSIC_MSG << endl;
- cout << "nop" << endl;
- nop_test();
-
-
- cout << "int16_t, big16_t" << endl;
+ cout << endl << "int16_t, big16_t" << endl;
test(0x1122);
- cout << "uint16_t" << endl;
- test(0x1122U);
+ cout << endl << "int16_t, little16_t" << endl;
+ test(0x1122);
- cout << "int32_t, big32_t" << endl;
+ cout << endl << "int32_t, big32_t" << endl;
test(0x11223344);
- cout << "uint32_t, ubig32_t" << endl;
- test(0x11223344UL);
+ cout << endl << "int32_t, little32_t" << endl;
+ test(0x11223344);
- cout << "int64_t, big64_t" << endl;
+ cout << endl << "int64_t, big64_t" << endl;
test(0x1122334455667788);
- cout << "uint64_t, ubig64_t" << endl;
- test(0x1122334455667788ULL);
+ cout << endl << "int64_t, little64_t" << endl;
+ test(0x1122334455667788);
//cout << "float" << endl;
//test(1.2345f);