summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/endian/test/loop_time_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/endian/test/loop_time_test.cpp')
-rw-r--r--src/boost/libs/endian/test/loop_time_test.cpp315
1 files changed, 315 insertions, 0 deletions
diff --git a/src/boost/libs/endian/test/loop_time_test.cpp b/src/boost/libs/endian/test/loop_time_test.cpp
new file mode 100644
index 00000000..82f33ea6
--- /dev/null
+++ b/src/boost/libs/endian/test/loop_time_test.cpp
@@ -0,0 +1,315 @@
+// loop_time_test.cpp ----------------------------------------------------------------//
+
+// Copyright Beman Dawes 2013
+
+// Distributed under the Boost Software License, Version 1.0.
+// http://www.boost.org/LICENSE_1_0.txt
+
+//--------------------------------------------------------------------------------------//
+
+//#define BOOST_ENDIAN_NO_INTRINSICS
+
+#include <boost/endian/detail/disable_warnings.hpp>
+
+#include <boost/endian/conversion.hpp>
+#include <boost/endian/arithmetic.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/timer/timer.hpp>
+#include <iostream>
+#include <cstdlib>
+#include <string>
+#include <boost/detail/lightweight_main.hpp>
+
+#ifdef _MSC_VER
+# pragma warning (push)
+# pragma warning (disable : 4459)
+#endif
+#include <boost/lexical_cast.hpp>
+#ifdef _MSC_VER
+# pragma warning (pop)
+#endif
+
+using namespace boost;
+using namespace boost::endian;
+
+using std::cout;
+using std::endl;
+
+namespace
+{
+ typedef boost::timer::nanosecond_type nanosecond_t;
+ std::string command_args;
+ uint64_t n; // number of test cases to run
+ int places = 2; // decimal places for times
+ bool verbose (false);
+ bool time_aligned (true);
+ bool time_unaligned (true);
+ bool time_16(true);
+ bool time_32(true);
+ bool time_64(true);
+
+ 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 = 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 if (*(argv[2] + 1) == 'a')
+ time_unaligned = false;
+ else if (*(argv[2] + 1) == 'u')
+ time_aligned = false;
+ else if (*(argv[2] + 1) == '1')
+ time_32 = time_64 = false;
+ else if (*(argv[2] + 1) == '3')
+ time_16 = time_64 = false;
+ else if (*(argv[2] + 1) == '6')
+ time_16 = time_32 = false;
+ else
+ {
+ cout << "Error - unknown option: " << argv[2] << "\n\n";
+ argc = -1;
+ break;
+ }
+ }
+
+ if (argc < 2)
+ {
+ cout << "Usage: loop_time_test 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"
+ " -a Aligned tests only\n"
+ " -u Unaligned tests only\n"
+ " -16 16-bit tests only\n"
+ " -32 32-bit tests only\n"
+ " -64 64-bit tests only\n"
+ ;
+ return std::exit(1);
+ }
+ }
+
+ std::string with_digit_separator(int64_t x)
+ {
+ std::string s = boost::lexical_cast<std::string>(x);
+ std::string s2;
+
+ for (std::string::size_type i = 0; i < s.size(); ++i)
+ {
+ if (i && ((s.size()-i) % 3) == 0)
+ s2 += '\'';
+ s2 += s[i];
+ }
+ return s2;
+ }
+
+//--------------------------------------------------------------------------------------//
+
+ template <class T, class EndianT>
+ void time()
+ {
+ T total = 0;
+ {
+ // cout << "*************Endian integer approach...\n";
+ EndianT x(0);
+ boost::timer::cpu_timer t;
+ for (uint64_t i = 0; i < n; ++i)
+ {
+ x += static_cast<T>(i);
+ }
+ t.stop();
+ total += x;
+ cout << "<td align=\"right\">" << t.format(places, "%t") << " s</td>";
+ }
+ {
+// cout << "***************Endian conversion approach...\n";
+ T x(0);
+ boost::timer::cpu_timer t;
+ native_to_big_inplace(x);
+ for (uint64_t i = 0; i < n; ++i)
+ {
+ x += static_cast<T>(i);
+ }
+ big_to_native_inplace(x);
+ t.stop();
+ native_to_big_inplace(x);
+ if (x != total)
+ throw std::logic_error("integer approach total != conversion approach total");
+ cout << "<td align=\"right\">" << t.format(places, "%t") << " s</td>";
+ }
+ }
+
+
+ void test_big_align_int16()
+ {
+ cout << "<tr><td>16-bit aligned big endian</td>";
+ time<int16_t, big_int16_at>();
+ cout << "</tr>\n";
+ }
+
+ void test_little_align_int16()
+ {
+ cout << "<tr><td>16-bit aligned little endian</td>";
+ time<int16_t, little_int16_at>();
+ cout << "</tr>\n";
+ }
+
+ void test_big_int16()
+ {
+ cout << "<tr><td>16-bit unaligned big endian</td>";
+ time<int16_t, big_int16_t>();
+ cout << "</tr>\n";
+ }
+
+ void test_little_int16()
+ {
+ cout << "<tr><td>16-bit unaligned little endian</td>";
+ time<int16_t, little_int16_t>();
+ cout << "</tr>\n";
+ }
+
+ void test_big_align_int32()
+ {
+ cout << "<tr><td>32-bit aligned big endian</td>";
+ time<int32_t, big_int32_at>();
+ cout << "</tr>\n";
+ }
+
+ void test_little_align_int32()
+ {
+ cout << "<tr><td>32-bit aligned little endian</td>";
+ time<int32_t, little_int32_at>();
+ cout << "</tr>\n";
+ }
+
+ void test_big_int32()
+ {
+ cout << "<tr><td>32-bit unaligned big endian</td>";
+ time<int32_t, big_int32_t>();
+ cout << "</tr>\n";
+ }
+
+ void test_little_int32()
+ {
+ cout << "<tr><td>32-bit unaligned little endian</td>";
+ time<int32_t, little_int32_t>();
+ cout << "</tr>\n";
+ }
+
+ void test_big_align_int64()
+ {
+ cout << "<tr><td>64-bit aligned big endian</td>";
+ time<int64_t, big_int64_at>();
+ cout << "</tr>\n";
+ }
+
+ void test_little_align_int64()
+ {
+ cout << "<tr><td>64-bit aligned little endian</td>";
+ time<int64_t, little_int64_at>();
+ cout << "</tr>\n";
+ }
+
+ void test_big_int64()
+ {
+ cout << "<tr><td>64-bit unaligned big endian</td>";
+ time<int64_t, big_int64_t>();
+ cout << "</tr>\n";
+ }
+
+ void test_little_int64()
+ {
+ cout << "<tr><td>64-bit unaligned little endian</td>";
+ time<int64_t, little_int64_t>();
+ cout << "</tr>\n";
+ }
+
+} // unnamed namespace
+
+//--------------------------------------------------------------------------------------//
+
+int cpp_main(int argc, char* argv[])
+{
+ process_command_line(argc, argv);
+
+ cout
+ << "<html>\n<head>\n<title>Endian Loop Time Test</title>\n</head>\n<body>\n"
+ << "<!-- boost-no-inspect -->\n"
+ << "<div align=\"center\"> <center>\n"
+ << "<table border=\"1\" cellpadding=\"5\" cellspacing=\"0\""
+ << "style=\"border-collapse: collapse\" bordercolor=\"#111111\">\n"
+ << "<tr><td colspan=\"6\" align=\"center\"><b>"
+ << BOOST_COMPILER << "</b></td></tr>\n"
+ << "<tr><td colspan=\"6\" align=\"center\"><b>"
+ << " Iterations: " << with_digit_separator(n)
+ << ", Intrinsics: " BOOST_ENDIAN_INTRINSIC_MSG
+ << "</b></td></tr>\n"
+ << "<tr><td><b>Test Case</b></td>\n"
+ "<td align=\"center\"><b>Endian<br>arithmetic<br>type</b></td>\n"
+ "<td align=\"center\"><b>Endian<br>conversion<br>function</b></td>\n"
+ "</tr>\n"
+ ;
+
+ if (time_aligned)
+ {
+ if (time_16)
+ {
+ test_big_align_int16();
+ test_little_align_int16();
+ }
+ if (time_32)
+ {
+ test_big_align_int32();
+ test_little_align_int32();
+ }
+ if (time_64)
+ {
+ test_big_align_int64();
+ test_little_align_int64();
+ }
+ }
+
+ if (time_unaligned)
+ {
+ if (time_16)
+ {
+ test_big_int16();
+ test_little_int16();
+ }
+ if (time_32)
+ {
+ test_big_int32();
+ test_little_int32();
+ }
+ if (time_64)
+ {
+ test_big_int64();
+ test_little_int64();
+ }
+ }
+
+ cout << "\n</div> </center>\n"
+ << "\n</table>\n</body>\n</html>\n";
+
+ return 0;
+}
+
+#include <boost/endian/detail/disable_warnings_pop.hpp>