Work-in-progress, including various bug fixes and doc updates.

This commit is contained in:
Beman
2015-01-14 16:28:30 -05:00
parent 321d5a087a
commit 810f5453a6
11 changed files with 225 additions and 122 deletions

View File

@@ -1,4 +1,4 @@
# Build endian/test/speed_test.cpp # Build and install benchmark programs
# Copyright Beman Dawes 2013 # Copyright Beman Dawes 2013
# Distributed under the Boost Software License, Version 1.0. # Distributed under the Boost Software License, Version 1.0.
@@ -7,16 +7,19 @@
project project
: source-location ../test : requirements : source-location ../test : requirements
<toolset>msvc:<asynch-exceptions>on <toolset>msvc:<asynch-exceptions>on
<library>/boost/timer//boost_timer
; ;
SOURCES = speed_test speed_test_functions ; SOURCES = speed_test speed_test_functions ;
exe "speed_test" exe "speed_test"
: $(SOURCES).cpp ../../timer/build//boost_timer : $(SOURCES).cpp
: <toolset>gcc:<cxxflags>-march=native : <toolset>gcc:<cxxflags>-march=native
; ;
exe "loop_time_test" exe "loop_time_test"
: loop_time_test.cpp ../../timer/build//boost_timer : loop_time_test.cpp
: <toolset>gcc:<cxxflags>-march=native : <toolset>gcc:<cxxflags>-march=native
; ;
install bin : speed_test loop_time_test ;

8
benchmark/test.bat Normal file
View File

@@ -0,0 +1,8 @@
b2 -a toolset=msvc-14.0 variant=release link=static address-model=64
bin\loop_time_test 1000 >msvc-loop-time.html
msvc-loop-time.html
echo The GCC build does not work, probably because of a bjam/b2 bug
b2 -a toolset=gcc-c++11 variant=release link=static address-model=64
bin\loop_time_test 1000 >gcc-loop-time.html
gcc-loop-time.html

View File

@@ -296,13 +296,60 @@ conversion from native to the desired output endianness.</p>
typically used regardless of record content or other circumstances</p> typically used regardless of record content or other circumstances</p>
<h4><a name="Convert-generally-as-needed-locally-in-anticipation">Convert <h4><a name="Convert-generally-as-needed-locally-in-anticipation">Convert
generally only as needed, but locally in anticipation of need</a></h4> only as needed, except locally in anticipation of need</a></h4>
<p>This pattern in general defers conversion but for specific local needs does <p>This pattern in general defers conversion but for specific local needs does
anticipatory conversion.</p> anticipatory conversion. Although particularly appropriate when coupled with the endian buffer
or arithmetic types, it also works well with the conversion functions.</p>
<p>This pattern is particularly appropriate when coupled with the endian buffer <p>Example:</p>
or arithmetic types.</p>
<blockquote>
<pre>struct data_t
{
big_int32_t v1;
big_int32_t v2;
big_int32_t v3;
};
data_t data;
read(data);
...
++v1;
...
int32_t v3_temp = data.v3; // hoist conversion out of loop
for (int32_t i = 0; i &lt; <i><b>large-number</b></i>; ++i)
{
... <i><b>lengthy computation that accesses </b></i>v3_temp<i><b> many times</b></i> ...
}
data.v3 = v3_temp;
write(data);
</pre>
</blockquote>
<p dir="ltr">In general the above pseudo-code leaves conversion up to the endian
arithmetic type <code>big_int32_t</code>. But to avoid conversion inside the
loop, a temporary is created before the loop is entered, and then used to set
the new value of <code>data.v3</code> after the loop is complete.</p>
<blockquote>
<p dir="ltr">Question: Won&#39;t the compiler&#39;s optimizer hoist the conversion out
of the loop anyhow?</p>
<p dir="ltr">Answer: VC++ 2015 Preview, and probably others, does not, even for
a toy test program. Although the savings is small (two register <code>
<span style="font-size: 85%">bswap</span></code> instructions), the cost might
be significant if the loop is repeated enough times. On the other hand, the
program may be so dominated by I/O time that even a lengthy loop will be
immaterial.</p>
</blockquote>
<h3><a name="Use-cases">Use case examples</a></h3> <h3><a name="Use-cases">Use case examples</a></h3>
@@ -363,7 +410,7 @@ arithmetic approach</a>.</p>
<hr> <hr>
<p>Last revised: <p>Last revised:
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->04 January, 2015<!--webbot bot="Timestamp" endspan i-checksum="38892" --></p> <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->08 January, 2015<!--webbot bot="Timestamp" endspan i-checksum="38900" --></p>
<p>© Copyright Beman Dawes, 2011, 2013, 2014</p> <p>© Copyright Beman Dawes, 2011, 2013, 2014</p>
<p>Distributed under the Boost Software License, Version 1.0. See <p>Distributed under the Boost Software License, Version 1.0. See
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p> <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p>

View File

@@ -200,6 +200,9 @@ intrinsics as a source of performance issues.</p>
<p>Consider this problem:</p> <p>Consider this problem:</p>
<div align="center">
<center>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
<tr> <tr>
<td colspan="2"> <td colspan="2">
@@ -240,15 +243,20 @@ native_to_big_inplace(x);
</tr> </tr>
</table> </table>
</center>
</div>
<p><b>There will be no performance difference between the two approaches in <p><b>There will be no performance difference between the two approaches in
release builds, release builds,
regardless of the native endianness of the machine.</b> That&#39;s because optimizing compilers will likely regardless of the native endianness of the machine.</b> That&#39;s because optimizing compilers will generate exactly the same code for each. That conclusion was confirmed by
generate exactly the same code for each. That conclusion was confirmed by
studying the generated assembly code for GCC and Visual C++. Furthermore, time studying the generated assembly code for GCC and Visual C++. Furthermore, time
spent doing I/O will determine the speed of this application.</p> spent doing I/O will determine the speed of this application.</p>
<p>Now consider a slightly different problem:&nbsp; </p> <p>Now consider a slightly different problem:&nbsp; </p>
<div align="center">
<center>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
<tr> <tr>
<td colspan="2"> <td colspan="2">
@@ -292,6 +300,9 @@ native_to_big_inplace(x);
</tr> </tr>
</table> </table>
</center>
</div>
<p>With the Endian arithmetic approach, on little endian platforms an implicit conversion from and then back to <p>With the Endian arithmetic approach, on little endian platforms an implicit conversion from and then back to
big endian is done inside the loop. With the Endian conversion function big endian is done inside the loop. With the Endian conversion function
approach, the user has ensured the conversions are done outside the loop, so the approach, the user has ensured the conversions are done outside the loop, so the
@@ -305,11 +316,12 @@ CPU @ 3.40GHz under Windows 7.</p>
<p><b>Caveat emptor: The Windows CPU timer has very high granularity. Repeated <p><b>Caveat emptor: The Windows CPU timer has very high granularity. Repeated
runs of the same tests often yield considerably different results.</b></p> runs of the same tests often yield considerably different results.</b></p>
<p>See <a href="../test/loop_time_test.cpp">loop_time_test.cpp</a> and <p>See <a href="../test/loop_time_test.cpp">loop_time_test.cpp</a> and
<a href="../build/Jamfile.v2">Jamfile.v2</a> for the actual code and build <a href="../benchmark/Jamfile.v2">Jamfile.v2</a> for the actual code and build
setup. setup.</p>
(For GCC 4.7, there are no 16-bit intrinsics, so they are emulated by using
32-bit intrinsics.)</p> <div align="center">
<center>
<table border="1" cellpadding="5" cellspacing="0"style="border-collapse: collapse" bordercolor="#111111"> <table border="1" cellpadding="5" cellspacing="0"style="border-collapse: collapse" bordercolor="#111111">
<tr><td colspan="6" align="center"><b><font size="2">GNU C++ version 4.7.0</font></b></td></tr> <tr><td colspan="6" align="center"><b><font size="2">GNU C++ version 4.7.0</font></b></td></tr>
@@ -399,10 +411,16 @@ setup.
</table> </table>
</center>
</div>
<p><b>Comment:</b> Note that the <b><font size="2">32-bit aligned big endian </font></b> <p><b>Comment:</b> Note that the <b><font size="2">32-bit aligned big endian </font></b>
timings are the same with or without intrinsics turned on. Presumably the timings are the same with or without intrinsics turned on. Presumably the
optimizer is recognizing the byte swapping and applying the intrinsics itself.</p> optimizer is recognizing the byte swapping and applying the intrinsics itself.</p>
<div align="center">
<center>
<table border="1" cellpadding="5" cellspacing="0"style="border-collapse: collapse" bordercolor="#111111"> <table border="1" cellpadding="5" cellspacing="0"style="border-collapse: collapse" bordercolor="#111111">
<tr><td colspan="6" align="center"><b><font size="2">Microsoft Visual C++ version 11.0</font></b></td></tr> <tr><td colspan="6" align="center"><b><font size="2">Microsoft Visual C++ version 11.0</font></b></td></tr>
<tr><td colspan="6" align="center"><b> <font size="2">Iterations: 1000000000, Intrinsics: cstdlib _byteswap_ushort, etc.</font></b></td></tr> <tr><td colspan="6" align="center"><b> <font size="2">Iterations: 1000000000, Intrinsics: cstdlib _byteswap_ushort, etc.</font></b></td></tr>
@@ -492,6 +510,10 @@ optimizer is recognizing the byte swapping and applying the intrinsics itself.</
</table> </table>
</center>
</div>
<h3><a name="Conclusions">Conclusions</a></h3> <h3><a name="Conclusions">Conclusions</a></h3>
<p>When program logic dictates many more conversions for the Endian arithmetic <p>When program logic dictates many more conversions for the Endian arithmetic
@@ -654,7 +676,7 @@ Blechmann, Tim Moore, tymofey, Tomas Puverle, Vincente Botet, Yuval Ronen and
Vitaly Budovsk. Apologies if anyone has been missed.</p> Vitaly Budovsk. Apologies if anyone has been missed.</p>
<hr> <hr>
<p>Last revised: <p>Last revised:
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->06 January, 2015<!--webbot bot="Timestamp" endspan i-checksum="38896" --></p> <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->12 January, 2015<!--webbot bot="Timestamp" endspan i-checksum="38889" --></p>
<p>© Copyright Beman Dawes, 2011, 2013</p> <p>© Copyright Beman Dawes, 2011, 2013</p>
<p>Distributed under the Boost Software License, Version 1.0. See <p>Distributed under the Boost Software License, Version 1.0. See
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p> <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p>

View File

@@ -3,6 +3,7 @@ body
{ {
font-family: sans-serif; font-family: sans-serif;
max-width: 6.5in; max-width: 6.5in;
margin: 0px auto;
font-size: 85%; font-size: 85%;
} }
ins {background-color: #CCFFCC;} ins {background-color: #CCFFCC;}
@@ -12,7 +13,7 @@ body
table{font-size: 100%;} table{font-size: 100%;}
/* /*
© Copyright Beman Dawes, 2014 <EFBFBD> Copyright Beman Dawes, 2014
Distributed under the Boost Software License, Version 1.0. Distributed under the Boost Software License, Version 1.0.
See www.boost.org/LICENSE_1_0.txt See www.boost.org/LICENSE_1_0.txt
*/ */

View File

@@ -16,8 +16,10 @@
#include <boost/endian/arithmetic.hpp> #include <boost/endian/arithmetic.hpp>
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
#include <boost/timer/timer.hpp> #include <boost/timer/timer.hpp>
#include <boost/lexical_cast.hpp>
#include <iostream> #include <iostream>
#include <cstdlib> #include <cstdlib>
#include <string>
#include <boost/detail/lightweight_main.hpp> #include <boost/detail/lightweight_main.hpp>
using namespace boost; using namespace boost;
@@ -47,7 +49,7 @@ namespace
if (argc >=2) if (argc >=2)
#ifndef _MSC_VER #ifndef _MSC_VER
n = std::atoll(argv[1]); n = atoll(argv[1]);
#else #else
n = _atoi64(argv[1]); n = _atoi64(argv[1]);
#endif #endif
@@ -77,6 +79,20 @@ namespace
} }
} }
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> template <class T, class EndianT>
@@ -208,36 +224,37 @@ int cpp_main(int argc, char* argv[])
cout cout
<< "<html>\n<head>\n<title>Endian Loop Time Test</title>\n</head>\n<body>\n" << "<html>\n<head>\n<title>Endian Loop Time Test</title>\n</head>\n<body>\n"
<< "<div align=\"center\"> <center>\n"
<< "<table border=\"1\" cellpadding=\"5\" cellspacing=\"0\"" << "<table border=\"1\" cellpadding=\"5\" cellspacing=\"0\""
<< "style=\"border-collapse: collapse\" bordercolor=\"#111111\">\n" << "style=\"border-collapse: collapse\" bordercolor=\"#111111\">\n"
<< "<tr><td colspan=\"6\" align=\"center\"><b>" << "<tr><td colspan=\"6\" align=\"center\"><b>"
<< BOOST_COMPILER << "</b></td></tr>\n" << BOOST_COMPILER << "</b></td></tr>\n"
<< "<tr><td colspan=\"6\" align=\"center\"><b>" << "<tr><td colspan=\"6\" align=\"center\"><b>"
<< " Iterations: " << n << " Iterations: " << with_digit_separator(n)
<< ", Intrinsics: " BOOST_ENDIAN_INTRINSIC_MSG << ", Intrinsics: " BOOST_ENDIAN_INTRINSIC_MSG
<< "</b></td></tr>\n" << "</b></td></tr>\n"
<< "<tr><td><b>Test Case</b></td>\n" << "<tr><td><b>Test Case</b></td>\n"
"<td align=\"center\"><b>Endian<br>type</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" "<td align=\"center\"><b>Endian<br>conversion<br>function</b></td>\n"
"</tr>\n" "</tr>\n"
; ;
test_big_align_int16(); test_big_align_int16();
test_little_align_int16(); test_little_align_int16();
test_big_int16();
test_little_int16();
test_big_align_int32(); test_big_align_int32();
test_little_align_int32(); test_little_align_int32();
test_big_int32();
test_little_int32();
test_big_align_int64(); test_big_align_int64();
test_little_align_int64(); test_little_align_int64();
test_big_int16();
test_little_int16();
test_big_int32();
test_little_int32();
test_big_int64(); test_big_int64();
test_little_int64(); test_little_int64();
cout << "\n</table>\n</body>\n</html>\n"; cout << "\n</div> </center>\n"
<< "\n</table>\n</body>\n</html>\n";
return 0; return 0;
} }

View File

@@ -25,12 +25,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loop_time_test", "loop_time
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "buffer_test", "buffer_test\buffer_test.vcxproj", "{BFB68CF4-EB92-4E5C-9694-A939496C5CDE}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "buffer_test", "buffer_test\buffer_test.vcxproj", "{BFB68CF4-EB92-4E5C-9694-A939496C5CDE}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uses_cases", "uses_cases\uses_cases.vcxproj", "{36BF451A-EAEF-4140-92E4-6EA461A26107}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "conversion_use_case", "conversion_use_case\conversion_use_case.vcxproj", "{1139E765-DE0F-497A-A7D9-EB2683521DF1}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "conversion_use_case", "conversion_use_case\conversion_use_case.vcxproj", "{1139E765-DE0F-497A-A7D9-EB2683521DF1}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "associated-files", "associated-files\associated-files.vcxproj", "{D9C80FE0-20A6-4711-A3F4-676019BD5A06}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "associated-files", "associated-files\associated-files.vcxproj", "{D9C80FE0-20A6-4711-A3F4-676019BD5A06}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "experiment", "experiment\experiment.vcxproj", "{CE9D8719-6E86-41D0-97CA-5BE5272594E9}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
@@ -123,11 +123,6 @@ Global
{BFB68CF4-EB92-4E5C-9694-A939496C5CDE}.Release|Win32.Build.0 = Release|Win32 {BFB68CF4-EB92-4E5C-9694-A939496C5CDE}.Release|Win32.Build.0 = Release|Win32
{BFB68CF4-EB92-4E5C-9694-A939496C5CDE}.Release|x64.ActiveCfg = Release|x64 {BFB68CF4-EB92-4E5C-9694-A939496C5CDE}.Release|x64.ActiveCfg = Release|x64
{BFB68CF4-EB92-4E5C-9694-A939496C5CDE}.Release|x64.Build.0 = Release|x64 {BFB68CF4-EB92-4E5C-9694-A939496C5CDE}.Release|x64.Build.0 = Release|x64
{36BF451A-EAEF-4140-92E4-6EA461A26107}.Debug|Win32.ActiveCfg = Debug|Win32
{36BF451A-EAEF-4140-92E4-6EA461A26107}.Debug|x64.ActiveCfg = Debug|x64
{36BF451A-EAEF-4140-92E4-6EA461A26107}.Release|Win32.ActiveCfg = Release|Win32
{36BF451A-EAEF-4140-92E4-6EA461A26107}.Release|Win32.Build.0 = Release|Win32
{36BF451A-EAEF-4140-92E4-6EA461A26107}.Release|x64.ActiveCfg = Release|Win32
{1139E765-DE0F-497A-A7D9-EB2683521DF1}.Debug|Win32.ActiveCfg = Debug|Win32 {1139E765-DE0F-497A-A7D9-EB2683521DF1}.Debug|Win32.ActiveCfg = Debug|Win32
{1139E765-DE0F-497A-A7D9-EB2683521DF1}.Debug|Win32.Build.0 = Debug|Win32 {1139E765-DE0F-497A-A7D9-EB2683521DF1}.Debug|Win32.Build.0 = Debug|Win32
{1139E765-DE0F-497A-A7D9-EB2683521DF1}.Debug|x64.ActiveCfg = Debug|x64 {1139E765-DE0F-497A-A7D9-EB2683521DF1}.Debug|x64.ActiveCfg = Debug|x64
@@ -144,6 +139,12 @@ Global
{D9C80FE0-20A6-4711-A3F4-676019BD5A06}.Release|Win32.Build.0 = Release|Win32 {D9C80FE0-20A6-4711-A3F4-676019BD5A06}.Release|Win32.Build.0 = Release|Win32
{D9C80FE0-20A6-4711-A3F4-676019BD5A06}.Release|x64.ActiveCfg = Release|x64 {D9C80FE0-20A6-4711-A3F4-676019BD5A06}.Release|x64.ActiveCfg = Release|x64
{D9C80FE0-20A6-4711-A3F4-676019BD5A06}.Release|x64.Build.0 = Release|x64 {D9C80FE0-20A6-4711-A3F4-676019BD5A06}.Release|x64.Build.0 = Release|x64
{CE9D8719-6E86-41D0-97CA-5BE5272594E9}.Debug|Win32.ActiveCfg = Debug|Win32
{CE9D8719-6E86-41D0-97CA-5BE5272594E9}.Debug|Win32.Build.0 = Debug|Win32
{CE9D8719-6E86-41D0-97CA-5BE5272594E9}.Debug|x64.ActiveCfg = Debug|Win32
{CE9D8719-6E86-41D0-97CA-5BE5272594E9}.Release|Win32.ActiveCfg = Release|Win32
{CE9D8719-6E86-41D0-97CA-5BE5272594E9}.Release|Win32.Build.0 = Release|Win32
{CE9D8719-6E86-41D0-97CA-5BE5272594E9}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@@ -97,7 +97,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>"$(TargetDir)\$(TargetName).exe" 1</Command> <Command>"$(TargetDir)\$(TargetName).exe" 1234</Command>
</PostBuildEvent> </PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -133,7 +133,7 @@
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>"$(TargetDir)\$(TargetName).exe" 1000000000</Command> <Command>"$(TargetDir)\$(TargetName).exe" 100000000</Command>
</PostBuildEvent> </PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

View File

@@ -48,7 +48,7 @@ namespace
if (argc >=2) if (argc >=2)
#ifndef _MSC_VER #ifndef _MSC_VER
n = std::atoll(argv[1]); n = atoll(argv[1]);
#else #else
n = _atoi64(argv[1]); n = _atoi64(argv[1]);
#endif #endif
@@ -97,60 +97,60 @@ namespace
void test_big_int16() void test_big_int16()
{ {
cout << "<tr><td>16-bit aligned big endian</td>"; cout << "<tr><td>16-bit aligned big endian</td>";
time<int16_t, big_int16_ut>(user::return_x_big_int16); time<int16_t, big_int16_t>(user::return_x_big_int16);
time<int16_t, big_int16_ut>(user::return_x_value_big_int16); time<int16_t, big_int16_t>(user::return_x_value_big_int16);
time<int16_t, big_int16_ut>(user::return_x_inplace_big_int16); time<int16_t, big_int16_t>(user::return_x_inplace_big_int16);
time<int16_t, big_int16_ut>(user::return_x_big_int16); time<int16_t, big_int16_t>(user::return_y_big_int16);
cout << "</tr>\n"; cout << "</tr>\n";
} }
void test_little_int16() void test_little_int16()
{ {
cout << "<tr><td>16-bit aligned little endian</td>"; cout << "<tr><td>16-bit aligned little endian</td>";
time<int16_t, little_int16_ut>(user::return_x_little_int16); time<int16_t, little_int16_t>(user::return_x_little_int16);
time<int16_t, little_int16_ut>(user::return_x_value_little_int16); time<int16_t, little_int16_t>(user::return_x_value_little_int16);
time<int16_t, little_int16_ut>(user::return_x_inplace_little_int16); time<int16_t, little_int16_t>(user::return_x_inplace_little_int16);
time<int16_t, little_int16_ut>(user::return_x_little_int16); time<int16_t, little_int16_t>(user::return_y_little_int16);
cout << "</tr>\n"; cout << "</tr>\n";
} }
void test_big_int32() void test_big_int32()
{ {
cout << "<tr><td>32-bit aligned big endian</td>"; cout << "<tr><td>32-bit aligned big endian</td>";
time<int32_t, big_int32_ut>(user::return_x_big_int32); time<int32_t, big_int32_t>(user::return_x_big_int32);
time<int32_t, big_int32_ut>(user::return_x_value_big_int32); time<int32_t, big_int32_t>(user::return_x_value_big_int32);
time<int32_t, big_int32_ut>(user::return_x_inplace_big_int32); time<int32_t, big_int32_t>(user::return_x_inplace_big_int32);
time<int32_t, big_int32_ut>(user::return_x_big_int32); time<int32_t, big_int32_t>(user::return_y_big_int32);
cout << "</tr>\n"; cout << "</tr>\n";
} }
void test_little_int32() void test_little_int32()
{ {
cout << "<tr><td>32-bit aligned little endian</td>"; cout << "<tr><td>32-bit aligned little endian</td>";
time<int32_t, little_int32_ut>(user::return_x_little_int32); time<int32_t, little_int32_t>(user::return_x_little_int32);
time<int32_t, little_int32_ut>(user::return_x_value_little_int32); time<int32_t, little_int32_t>(user::return_x_value_little_int32);
time<int32_t, little_int32_ut>(user::return_x_inplace_little_int32); time<int32_t, little_int32_t>(user::return_x_inplace_little_int32);
time<int32_t, little_int32_ut>(user::return_x_little_int32); time<int32_t, little_int32_t>(user::return_y_little_int32);
cout << "</tr>\n"; cout << "</tr>\n";
} }
void test_big_int64() void test_big_int64()
{ {
cout << "<tr><td>64-bit aligned big endian</td>"; cout << "<tr><td>64-bit aligned big endian</td>";
time<int64_t, big_int64_ut>(user::return_x_big_int64); time<int64_t, big_int64_t>(user::return_x_big_int64);
time<int64_t, big_int64_ut>(user::return_x_value_big_int64); time<int64_t, big_int64_t>(user::return_x_value_big_int64);
time<int64_t, big_int64_ut>(user::return_x_inplace_big_int64); time<int64_t, big_int64_t>(user::return_x_inplace_big_int64);
time<int64_t, big_int64_ut>(user::return_x_big_int64); time<int64_t, big_int64_t>(user::return_y_big_int64);
cout << "</tr>\n"; cout << "</tr>\n";
} }
void test_little_int64() void test_little_int64()
{ {
cout << "<tr><td>64-bit aligned little endian</td>"; cout << "<tr><td>64-bit aligned little endian</td>";
time<int64_t, little_int64_ut>(user::return_x_little_int64); time<int64_t, little_int64_t>(user::return_x_little_int64);
time<int64_t, little_int64_ut>(user::return_x_value_little_int64); time<int64_t, little_int64_t>(user::return_x_value_little_int64);
time<int64_t, little_int64_ut>(user::return_x_inplace_little_int64); time<int64_t, little_int64_t>(user::return_x_inplace_little_int64);
time<int64_t, little_int64_ut>(user::return_x_little_int64); time<int64_t, little_int64_t>(user::return_y_little_int64);
cout << "</tr>\n"; cout << "</tr>\n";
} }

View File

@@ -26,67 +26,71 @@
namespace user namespace user
{ {
int16_t return_x_big_int16(int16_t x, big_int16_ut) BOOST_NOEXCEPT { return x; } int16_t return_x_big_int16(int16_t x, big_int16_t) BOOST_NOEXCEPT { return x; }
int16_t return_x_little_int16(int16_t x, little_int16_ut) BOOST_NOEXCEPT { return x; } int16_t return_x_little_int16(int16_t x, little_int16_t) BOOST_NOEXCEPT { return x; }
int16_t return_x_value_big_int16(int16_t x, big_int16_ut) BOOST_NOEXCEPT int16_t return_x_value_big_int16(int16_t x, big_int16_t) BOOST_NOEXCEPT
{ {
return conditional_reverse<order::native, order::big>(x); return conditional_reverse<order::native, order::big>(x);
} }
int16_t return_x_value_little_int16(int16_t x, little_int16_ut) BOOST_NOEXCEPT int16_t return_x_value_little_int16(int16_t x, little_int16_t) BOOST_NOEXCEPT
{ {
return conditional_reverse<order::native, order::little>(x); return conditional_reverse<order::native, order::little>(x);
} }
int16_t return_x_inplace_big_int16(int16_t x, big_int16_ut) BOOST_NOEXCEPT int16_t return_x_inplace_big_int16(int16_t x, big_int16_t) BOOST_NOEXCEPT
{ {
conditional_reverse_inplace<order::native, order::big>(x); return x; conditional_reverse_inplace<order::native, order::big>(x); return x;
} }
int16_t return_x_inplace_little_int16(int16_t x, little_int16_ut) BOOST_NOEXCEPT int16_t return_x_inplace_little_int16(int16_t x, little_int16_t) BOOST_NOEXCEPT
{ {
conditional_reverse_inplace<order::native, order::little>(x); return x; conditional_reverse_inplace<order::native, order::little>(x); return x;
} }
int16_t return_y_big_int16(int16_t x, big_int16_ut y) BOOST_NOEXCEPT { return y; } int16_t return_y_big_int16(int16_t x, big_int16_t y) BOOST_NOEXCEPT { return y; }
int16_t return_y_little_int16(int16_t x, little_int16_ut y) BOOST_NOEXCEPT { return y; } int16_t return_y_little_int16(int16_t x, little_int16_t y) BOOST_NOEXCEPT { return y; }
int32_t return_x_big_int32(int32_t x, big_int32_ut) BOOST_NOEXCEPT { return x; } //------------------------------------------------------------------------------------//
int32_t return_x_little_int32(int32_t x, little_int32_ut) BOOST_NOEXCEPT { return x; }
int32_t return_x_value_big_int32(int32_t x, big_int32_ut) BOOST_NOEXCEPT
{
return conditional_reverse<order::native, order::big>(x);
}
int32_t return_x_value_little_int32(int32_t x, little_int32_ut) BOOST_NOEXCEPT
{
return conditional_reverse<order::native, order::little>(x);
}
int32_t return_x_inplace_big_int32(int32_t x, big_int32_ut) BOOST_NOEXCEPT
{
conditional_reverse_inplace<order::native, order::big>(x); return x;
}
int32_t return_x_inplace_little_int32(int32_t x, little_int32_ut) BOOST_NOEXCEPT
{
conditional_reverse_inplace<order::native, order::little>(x); return x;
}
int32_t return_y_big_int32(int32_t x, big_int32_ut y) BOOST_NOEXCEPT { return y; }
int32_t return_y_little_int32(int32_t x, little_int32_ut y) BOOST_NOEXCEPT { return y; }
int64_t return_x_big_int64(int64_t x, big_int64_ut) BOOST_NOEXCEPT { return x; } int32_t return_x_big_int32(int32_t x, big_int32_t) BOOST_NOEXCEPT { return x; }
int64_t return_x_little_int64(int64_t x, little_int64_ut) BOOST_NOEXCEPT { return x; } int32_t return_x_little_int32(int32_t x, little_int32_t) BOOST_NOEXCEPT { return x; }
int64_t return_x_value_big_int64(int64_t x, big_int64_ut) BOOST_NOEXCEPT int32_t return_x_value_big_int32(int32_t x, big_int32_t) BOOST_NOEXCEPT
{ {
return conditional_reverse<order::native, order::big>(x); return conditional_reverse<order::native, order::big>(x);
} }
int64_t return_x_value_little_int64(int64_t x, little_int64_ut) BOOST_NOEXCEPT int32_t return_x_value_little_int32(int32_t x, little_int32_t) BOOST_NOEXCEPT
{ {
return conditional_reverse<order::native, order::little>(x); return conditional_reverse<order::native, order::little>(x);
} }
int64_t return_x_inplace_big_int64(int64_t x, big_int64_ut) BOOST_NOEXCEPT int32_t return_x_inplace_big_int32(int32_t x, big_int32_t) BOOST_NOEXCEPT
{ {
conditional_reverse_inplace<order::native, order::big>(x); return x; conditional_reverse_inplace<order::native, order::big>(x); return x;
} }
int64_t return_x_inplace_little_int64(int64_t x, little_int64_ut) BOOST_NOEXCEPT int32_t return_x_inplace_little_int32(int32_t x, little_int32_t) BOOST_NOEXCEPT
{ {
conditional_reverse_inplace<order::native, order::little>(x); return x; conditional_reverse_inplace<order::native, order::little>(x); return x;
} }
int64_t return_y_big_int64(int64_t x, big_int64_ut y) BOOST_NOEXCEPT { return y; } int32_t return_y_big_int32(int32_t x, big_int32_t y) BOOST_NOEXCEPT { return y; }
int64_t return_y_little_int64(int64_t x, little_int64_ut y) BOOST_NOEXCEPT { return y; } int32_t return_y_little_int32(int32_t x, little_int32_t y) BOOST_NOEXCEPT { return y; }
//------------------------------------------------------------------------------------//
int64_t return_x_big_int64(int64_t x, big_int64_t) BOOST_NOEXCEPT { return x; }
int64_t return_x_little_int64(int64_t x, little_int64_t) BOOST_NOEXCEPT { return x; }
int64_t return_x_value_big_int64(int64_t x, big_int64_t) BOOST_NOEXCEPT
{
return conditional_reverse<order::native, order::big>(x);
}
int64_t return_x_value_little_int64(int64_t x, little_int64_t) BOOST_NOEXCEPT
{
return conditional_reverse<order::native, order::little>(x);
}
int64_t return_x_inplace_big_int64(int64_t x, big_int64_t) BOOST_NOEXCEPT
{
conditional_reverse_inplace<order::native, order::big>(x); return x;
}
int64_t return_x_inplace_little_int64(int64_t x, little_int64_t) BOOST_NOEXCEPT
{
conditional_reverse_inplace<order::native, order::little>(x); return x;
}
int64_t return_y_big_int64(int64_t x, big_int64_t y) BOOST_NOEXCEPT { return y; }
int64_t return_y_little_int64(int64_t x, little_int64_t y) BOOST_NOEXCEPT { return y; }
} }

View File

@@ -24,32 +24,32 @@ namespace user
using namespace boost; using namespace boost;
using namespace boost::endian; using namespace boost::endian;
int16_t return_x_big_int16(int16_t x, big_int16_ut y) BOOST_NOEXCEPT; int16_t return_x_big_int16(int16_t x, big_int16_t y) BOOST_NOEXCEPT;
int16_t return_x_little_int16(int16_t x, little_int16_ut y) BOOST_NOEXCEPT; int16_t return_x_little_int16(int16_t x, little_int16_t y) BOOST_NOEXCEPT;
int16_t return_x_value_big_int16(int16_t x, big_int16_ut) BOOST_NOEXCEPT; int16_t return_x_value_big_int16(int16_t x, big_int16_t) BOOST_NOEXCEPT;
int16_t return_x_value_little_int16(int16_t x, little_int16_ut y) BOOST_NOEXCEPT; int16_t return_x_value_little_int16(int16_t x, little_int16_t y) BOOST_NOEXCEPT;
int16_t return_x_inplace_big_int16(int16_t x, big_int16_ut y) BOOST_NOEXCEPT; int16_t return_x_inplace_big_int16(int16_t x, big_int16_t y) BOOST_NOEXCEPT;
int16_t return_x_inplace_little_int16(int16_t x, little_int16_ut y) BOOST_NOEXCEPT; int16_t return_x_inplace_little_int16(int16_t x, little_int16_t y) BOOST_NOEXCEPT;
int16_t return_y_big_int16(int16_t x, big_int16_ut y) BOOST_NOEXCEPT; int16_t return_y_big_int16(int16_t x, big_int16_t y) BOOST_NOEXCEPT;
int16_t return_y_little_int16(int16_t x, little_int16_ut y) BOOST_NOEXCEPT; int16_t return_y_little_int16(int16_t x, little_int16_t y) BOOST_NOEXCEPT;
int32_t return_x_big_int32(int32_t x, big_int32_ut y) BOOST_NOEXCEPT; int32_t return_x_big_int32(int32_t x, big_int32_t y) BOOST_NOEXCEPT;
int32_t return_x_little_int32(int32_t x, little_int32_ut y) BOOST_NOEXCEPT; int32_t return_x_little_int32(int32_t x, little_int32_t y) BOOST_NOEXCEPT;
int32_t return_x_value_big_int32(int32_t x, big_int32_ut) BOOST_NOEXCEPT; int32_t return_x_value_big_int32(int32_t x, big_int32_t) BOOST_NOEXCEPT;
int32_t return_x_value_little_int32(int32_t x, little_int32_ut y) BOOST_NOEXCEPT; int32_t return_x_value_little_int32(int32_t x, little_int32_t y) BOOST_NOEXCEPT;
int32_t return_x_inplace_big_int32(int32_t x, big_int32_ut y) BOOST_NOEXCEPT; int32_t return_x_inplace_big_int32(int32_t x, big_int32_t y) BOOST_NOEXCEPT;
int32_t return_x_inplace_little_int32(int32_t x, little_int32_ut y) BOOST_NOEXCEPT; int32_t return_x_inplace_little_int32(int32_t x, little_int32_t y) BOOST_NOEXCEPT;
int32_t return_y_big_int32(int32_t x, big_int32_ut y) BOOST_NOEXCEPT; int32_t return_y_big_int32(int32_t x, big_int32_t y) BOOST_NOEXCEPT;
int32_t return_y_little_int32(int32_t x, little_int32_ut y) BOOST_NOEXCEPT; int32_t return_y_little_int32(int32_t x, little_int32_t y) BOOST_NOEXCEPT;
int64_t return_x_big_int64(int64_t x, big_int64_ut y) BOOST_NOEXCEPT; int64_t return_x_big_int64(int64_t x, big_int64_t y) BOOST_NOEXCEPT;
int64_t return_x_little_int64(int64_t x, little_int64_ut y) BOOST_NOEXCEPT; int64_t return_x_little_int64(int64_t x, little_int64_t y) BOOST_NOEXCEPT;
int64_t return_x_value_big_int64(int64_t x, big_int64_ut) BOOST_NOEXCEPT; int64_t return_x_value_big_int64(int64_t x, big_int64_t) BOOST_NOEXCEPT;
int64_t return_x_value_little_int64(int64_t x, little_int64_ut y) BOOST_NOEXCEPT; int64_t return_x_value_little_int64(int64_t x, little_int64_t y) BOOST_NOEXCEPT;
int64_t return_x_inplace_big_int64(int64_t x, big_int64_ut y) BOOST_NOEXCEPT; int64_t return_x_inplace_big_int64(int64_t x, big_int64_t y) BOOST_NOEXCEPT;
int64_t return_x_inplace_little_int64(int64_t x, little_int64_ut y) BOOST_NOEXCEPT; int64_t return_x_inplace_little_int64(int64_t x, little_int64_t y) BOOST_NOEXCEPT;
int64_t return_y_big_int64(int64_t x, big_int64_ut y) BOOST_NOEXCEPT; int64_t return_y_big_int64(int64_t x, big_int64_t y) BOOST_NOEXCEPT;
int64_t return_y_little_int64(int64_t x, little_int64_ut y) BOOST_NOEXCEPT; int64_t return_y_little_int64(int64_t x, little_int64_t y) BOOST_NOEXCEPT;
} }