From e9ae69f3d05ad0b675dac5977f397921914dbeb8 Mon Sep 17 00:00:00 2001 From: Beman Date: Sat, 17 Jan 2015 16:53:41 -0500 Subject: [PATCH] Don another pass through the docs. --- doc/arithmetic.html | 14 +- doc/buffers.html | 86 +++++++----- doc/choosing_approach.html | 14 +- doc/conversion.html | 20 +-- doc/index.html | 260 +++++-------------------------------- doc/todo_list.html | 134 +------------------ 6 files changed, 96 insertions(+), 432 deletions(-) diff --git a/doc/arithmetic.html b/doc/arithmetic.html index 56088f3..f9af025 100644 --- a/doc/arithmetic.html +++ b/doc/arithmetic.html @@ -65,17 +65,7 @@ Acknowledgements - - - Headers - - - - <boost/endian/conversion.hpp>
- <boost/endian/buffers.hpp>
- <boost/endian/arithmetic.hpp> - - +

Introduction

Header boost/endian/arithmetic.hpp provides integer and floating point binary types with control over @@ -682,7 +672,7 @@ differs from endian representation size. Vicente Botet and other reviewers suggested supporting floating point types.


Last revised: -04 January, 2015

+17 January, 2015

© Copyright Beman Dawes, 2006-2009, 2013

Distributed under the Boost Software License, Version 1.0. See www.boost.org/ LICENSE_1_0.txt

diff --git a/doc/buffers.html b/doc/buffers.html index 65c3c01..26cd461 100644 --- a/doc/buffers.html +++ b/doc/buffers.html @@ -54,30 +54,20 @@     Synopsis
    Members
+    Non-Members
FAQ
Design
C++11
Compilation - - - Headers - - - -

- <boost/endian/conversion.hpp>
- <boost/endian/buffers.hpp>
- <boost/endian/arithmetic.hpp> - - +

Introduction

The internal byte order of arithmetic types is traditionally called endianness. See the Wikipedia for a full exploration of endianness, including definitions of big endian and little endian.

-

Header boost/endian/buffers.hpp +

Header boost/endian/buffers.hpp provides endian_buffer, a portable endian integer and floating-point binary buffer class template with control over byte order, value type, size, and alignment independent of the platform's native @@ -94,22 +84,23 @@ base class for the endian_arithmetic class template, which is aimed at users who wish fully automatic endianness conversion and direct support for all normal arithmetic operations.

Example

-

The endian_example.cpp program writes a +

The example/endian_example.cpp program writes a binary file containing four byte big-endian and little-endian integers:

#include <iostream>
 #include <cstdio>
-#include <boost/endian/buffers.hpp>
+#include <boost/endian/buffers.hpp>  // see Synopsis below
 #include <boost/static_assert.hpp>
 
 using namespace boost::endian;
 
 namespace 
 {
-  //  This is an extract from a very widely used GIS file format. Why the designer
-  //  decided to mix big and little endians in the same file is not known. But
-  //  this is a real-world format and users wishing to write low level code
-  //  manipulating these files have to deal with the mixed endianness.
+  //  This is an extract from a very widely used GIS file format.
+  //  Why the designer decided to mix big and little endians in
+  //  the same file is not known. But this is a real-world format
+  //  and users wishing to write low level code manipulating these
+  //  files have to deal with the mixed endianness.
 
   struct header
   {
@@ -133,11 +124,13 @@ int main(int, char* [])
   h.version     = 1;
   h.shape_type  = 0x01020304;
 
-  //  Low-level I/O such as POSIX read/write or <cstdio> fread/fwrite is sometimes
-  //  used for binary file operations when ultimate efficiency is important. Such
-  //  I/O is often performed in some C++ wrapper class, but to drive home the
-  //  point that endian integers are often used in fairly low-level code that does
-  //  bulk I/O operations, <cstdio> fopen/fwrite is used for I/O in this example.
+  //  Low-level I/O such as POSIX read/write or <cstdio>
+  //  fread/fwrite is sometimes used for binary file operations
+  //  when ultimate efficiency is important. Such I/O is often
+  //  performed in some C++ wrapper class, but to drive home the
+  //  point that endian integers are often used in fairly
+  //  low-level code that does bulk I/O operations, <cstdio>
+  //  fopen/fwrite is used for I/O in this example.
 
   std::FILE* fi = std::fopen(filename, "wb");  // MUST BE BINARY
   
@@ -161,7 +154,7 @@ int main(int, char* [])
 }
 
-

After compiling and executing endian_example.cpp, +

After compiling and executing example/endian_example.cpp, a hex dump of test.dat shows:

01020304 00000010 01000000 04030201
@@ -340,7 +333,7 @@ requirements vary between hardware architectures and because alignment may be affected by compiler switches or pragmas. For example, alignment of an 64-bit integer may be to a 32-bit boundary on a 32-bit machine. Furthermore, aligned types are only available on architectures with 16, 32, and 64-bit integer types.

-

Note: One-byte types +

Note: One-byte big and little buffer types have identical functionality. They are provided to improve code readability and searchability.

Class template endian_buffer

@@ -380,18 +373,18 @@ usual operations on integers are supplied.

}; // stream inserter - template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T, - std::size_t n_bits, BOOST_SCOPED_ENUM(align) A> + template <class charT, class traits, order Order, class T, + std::size_t n_bits, align Align> std::basic_ostream<charT, traits>& - operator<<(std::basic_ostream<charT, traits>& os, - const endian_buffer<Order, T, n_bits, A>& x); + operator<<(std::basic_ostream<charT, traits>& os, + const endian_buffer<Order, T, n_bits, Align>& x); // stream extractor - template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T, - std::size_t n_bits, BOOST_SCOPED_ENUM(align) A> + template <class charT, class traits, order Order, class T, + std::size_t n_bits, align A> std::basic_istream<charT, traits>& - operator>>(std::basic_istream<charT, traits>& is, - endian_buffer<Order, T, n_bits, A>& x); + operator>>(std::basic_istream<charT, traits>& is, + endian_buffer<Order, T, n_bits, Align>& x); // typedefs @@ -494,7 +487,6 @@ usual operations on integers are supplied.

typedef implementation-defined_uint56_buf_ut native_uint56_buf_ut; typedef implementation-defined_uint64_buf_ut native_uint64_buf_ut; - } // namespace endian } // namespace boost

The implementation-defined text in typedefs above is either @@ -554,6 +546,30 @@ boost::endian::endian_reverse.

Returns: A pointer to the first byte of endian_value.

+

Non-member functions

+
template <class charT, class traits, order Order, class T,
+  std::size_t n_bits, align Align>
+std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os,
+  const endian_buffer<Order, T, n_bits, Align>& x);
+
+
+

Returns: os << x.value().

+
+
template <class charT, class traits, order Order, class T,
+  std::size_t n_bits, align A>
+std::basic_istream<charT, traits>& operator>>(std::basic_istream<charT, traits>& is,
+  endian_buffer<Order, T, n_bits, Align>& x);
+
+
+

Effects: As if:

+
+
T i;
+if (is >> i)
+  x = i;
+
+
+

Returns: is.

+

FAQ

See the Endian home page FAQ for a library-wide diff --git a/doc/choosing_approach.html b/doc/choosing_approach.html index b50386b..119d302 100644 --- a/doc/choosing_approach.html +++ b/doc/choosing_approach.html @@ -60,17 +60,7 @@ as needed, locally in anticipation
      Reliability and arithmetic-speed
      Reliability and ease-of-use - - - Headers - - - - <boost/endian/conversion.hpp>
- <boost/endian/buffers.hpp>
- <boost/endian/arithmetic.hpp> - - +

Introduction

@@ -410,7 +400,7 @@ arithmetic approach.


Last revised: -08 January, 2015

+17 January, 2015

© Copyright Beman Dawes, 2011, 2013, 2014

Distributed under the Boost Software License, Version 1.0. See www.boost.org/ LICENSE_1_0.txt

diff --git a/doc/conversion.html b/doc/conversion.html index f5df450..53d33d6 100644 --- a/doc/conversion.html +++ b/doc/conversion.html @@ -53,17 +53,7 @@ FAQ
Acknowledgements - - - Headers - - - - <boost/endian/conversion.hpp>
- <boost/endian/buffers.hpp>
- <boost/endian/arithmetic.hpp> - - +

Introduction

@@ -233,8 +223,7 @@ call to endian_reverse().

EndianReversibleInplace are required to perform reversal of endianness if needed by making an unqualified call to endian_reverse_inplace().

-

See -udt_conversion_example.cpp for an example user-defined type.

+

See example/udt_conversion_example.cpp for an example user-defined type.

Functions

int8_t   endian_reverse(int8_t x) noexcept;
@@ -372,12 +361,13 @@ portability for both programs and data.

Acknowledgements

Tomas Puverle was instrumental in identifying and articulating the need to -support endian conversion as separate from endian integer types. Phil Endecott suggested the form of the value returning signatures. Vicente Botet and other reviewers suggested supporting floating point types and user defined types. General reverse template implementation approach using std::reverse suggested by Mathias Gaunard. Portable implementation approach for 16, 32, and 64-bit integers suggested by tymofey, with avoidance of undefined behavior as suggested by Giovanni Piero Deretta, and a further refinement suggested by Pyry Jahkola. Intrinsic builtins implementation approach for 16, 32, and 64-bit integers suggested by several reviewers, and by David Stone, who provided his Boost licensed macro implementation that became the starting point for boost/endian/detail/intrinsic.hpp. +support endian conversion as separate from endian integer types. Phil Endecott suggested the form of the value returning signatures. Vicente Botet and other reviewers suggested supporting floating point types and user defined types. General reverse template implementation approach using std::reverse suggested by Mathias Gaunard. Portable implementation approach for 16, 32, and 64-bit integers suggested by tymofey, with avoidance of undefined behavior as suggested by Giovanni Piero Deretta, and a further refinement suggested by Pyry Jahkola. Intrinsic builtins implementation approach for 16, 32, and 64-bit integers suggested by several reviewers, and by David Stone, who provided his Boost licensed macro implementation that became the starting point for +boost/endian/detail/intrinsic.hpp. Pierre Talbot provided the int8_t endian_reverse() and templated endian_reverse_inplace() implementations.


Last revised: -04 January, 2015

+17 January, 2015

© Copyright Beman Dawes, 2011, 2013

Distributed under the Boost Software License, Version 1.0. See www.boost.org/ LICENSE_1_0.txt

diff --git a/doc/index.html b/doc/index.html index 0fce3e5..6836b0d 100644 --- a/doc/index.html +++ b/doc/index.html @@ -49,8 +49,7 @@   buffer types, and arithmetic types
Built-in support for Intrinsics
Performance
-   Timings for Example 2
-   Conclusions
+   Timings
Overall FAQ
Release history
   Changes @@ -60,17 +59,7 @@ formal review
Acknowledgements
- - - Headers - - - - <boost/endian/conversion.hpp>
- <boost/endian/buffers.hpp>
- <boost/endian/arithmetic.hpp> - - +

Abstract

@@ -308,236 +297,55 @@ 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 code may run more quickly on little endian platforms.

-

Timings for Example 2 (conversion functions hoisted -out of loop)

+

Timings

These tests were run against release builds on a circa 2012 4-core little endian X64 Intel Core i5-3570K CPU @ 3.40GHz under Windows 7.

Caveat emptor: The Windows CPU timer has very high granularity. Repeated runs of the same tests often yield considerably different results.

-

See loop_time_test.cpp and -Jamfile.v2 for the actual code and build +

See test/loop_time_test.cpp for the actual code and benchmark/Jamfile.v2 for the build setup.

-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
GNU C++ version 4.7.0
Iterations: 1000000000, Intrinsics: __builtin_bswap16, etc.
Test CaseEndian
arithmetic
Endian
conversion
function
16-bit aligned big endian1.37 s0.81 s
16-bit aligned little endian0.83 s0.81 s
16-bit unaligned big endian1.09 s0.83 s
16-bit unaligned little endian1.09 s0.81 s
32-bit aligned big endian0.98 s0.27 s
32-bit aligned little endian0.28 s0.27 s
32-bit unaligned big endian3.82 s0.27 s
32-bit unaligned little endian3.82 s0.27 s
64-bit aligned big endian1.65 s0.41 s
64-bit aligned little endian0.41 s0.41 s
64-bit unaligned big endian17.53 s0.41 s
64-bit unaligned little endian17.52 s0.41 s
Iterations: 1000000000, Intrinsics: no byte swap intrinsics
Test CaseEndian
arithmetic
Endian
conversion
function
16-bit aligned big endian1.95 s0.81 s
16-bit aligned little endian0.83 s0.81 s
16-bit unaligned big endian1.19 s0.81 s
16-bit unaligned little endian1.20 s0.81 s
32-bit aligned big endian0.97 s0.28 s
32-bit aligned little endian0.27 s0.28 s
32-bit unaligned big endian4.10 s0.27 s
32-bit unaligned little endian4.10 s0.27 s
64-bit aligned big endian1.64 s0.42 s
64-bit aligned little endian0.41 s0.41 s
64-bit unaligned big endian17.52 s0.42 s
64-bit unaligned little endian17.52 s0.41 s
- -
-
- -

Comment: Note that the 32-bit aligned big endian -timings are the same with or without intrinsics turned on. Presumably the -optimizer is recognizing the byte swapping and applying the intrinsics itself.

- - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + +
Microsoft Visual C++ version 11.0
Iterations: 1000000000, Intrinsics: cstdlib _byteswap_ushort, etc.
Test CaseEndian
type
Endian
conversion
function
GNU C++ version 4.8.2 on Linux virtual + machine
Iterations: 10'000'000'000, Intrinsics: __builtin_bswap16, etc.
Test CaseEndian
arithmetic
type
Endian
conversion
function
16-bit aligned big endian0.83 s0.51 s
16-bit aligned little endian0.51 s0.50 s
16-bit unaligned big endian1.37 s0.51 s
16-bit unaligned little endian1.37 s0.50 s
32-bit aligned big endian0.81 s0.50 s
32-bit aligned little endian0.51 s0.51 s
32-bit unaligned big endian2.98 s0.53 s
32-bit unaligned little endian3.00 s0.51 s
64-bit aligned big endian1.33 s0.33 s
64-bit aligned little endian0.34 s0.27 s
64-bit unaligned big endian7.05 s0.33 s
64-bit unaligned little endian7.11 s0.31 s
Iterations: 1000000000, Intrinsics: no byte swap intrinsics
Test CaseEndian
type
Endian
conversion
function
16-bit aligned big endian0.83 s0.51 s
16-bit aligned little endian0.51 s0.51 s
16-bit unaligned big endian1.36 s0.51 s
16-bit unaligned little endian1.37 s0.51 s
32-bit aligned big endian3.42 s0.50 s
32-bit aligned little endian0.51 s0.51 s
32-bit unaligned big endian2.93 s0.50 s
32-bit unaligned little endian2.95 s0.50 s
64-bit aligned big endian5.99 s0.33 s
64-bit aligned little endian0.33 s0.33 s
64-bit unaligned big endian7.02 s0.27 s
64-bit unaligned little endian7.02 s0.27 s
16-bit aligned big endian8.46 s5.28 s
16-bit aligned little endian5.28 s5.22 s
32-bit aligned big endian8.40 s2.11 s
32-bit aligned little endian2.11 s2.10 s
64-bit aligned big endian14.02 s3.10 s
64-bit aligned little endian3.00 s3.03 s
- -
+

- -

Conclusions

- -

When program logic dictates many more conversions for the Endian arithmetic -approach than the Endian conversion function approach (example -2):

- -
- -

There may be a considerable performance difference. If machine endianness differs from the -desired endianness, the Endian arithmetic approach must do the byte reversal many -times while the Endian conversion approach only does the reversal once. But if -the endianness is the same, there is no conversion with either approach and no -conversion code is generated for typical release builds.

- -

Whether or not compiler byte swap intrinsics are explicitly available has little -impact on GCC but a lot of impact on Visual C++, for the tested compiler -versions. Yet another example of why actual timing tests are needed to -determine if some coding technique has significant impact on performance.

- -

Unaligned types are much slower that aligned types, regardless of -endianness considerations. Instead of single instruction register loads and -stores, multiple instructions are required on common platforms.

- -
+
+ + + + + + + + + + + + + +
Microsoft Visual C++ version 14.0
Iterations: 10'000'000'000, Intrinsics: cstdlib _byteswap_ushort, etc.
Test CaseEndian
arithmetic
type
Endian
conversion
function
16-bit aligned big endian8.27 s5.26 s
16-bit aligned little endian5.29 s5.32 s
32-bit aligned big endian8.36 s5.24 s
32-bit aligned little endian5.24 s5.24 s
64-bit aligned big endian13.65 s3.34 s
64-bit aligned little endian3.35 s2.73 s
+

Overall FAQ

@@ -676,7 +484,7 @@ Blechmann, Tim Moore, tymofey, Tomas Puverle, Vincente Botet, Yuval Ronen and Vitaly Budovsk. Apologies if anyone has been missed.


Last revised: -12 January, 2015

+15 January, 2015

© Copyright Beman Dawes, 2011, 2013

Distributed under the Boost Software License, Version 1.0. See www.boost.org/ LICENSE_1_0.txt

diff --git a/doc/todo_list.html b/doc/todo_list.html index b4f3241..fed67d3 100644 --- a/doc/todo_list.html +++ b/doc/todo_list.html @@ -12,23 +12,9 @@

Endian Library TODO List

-

Last revised: -17 December, 2014

- -

August 12, 2014: The many items that have been completed should be -removed, after verifying that they are in fact taken care of.

To Do

-

Format Review Comments

-

Votes

+

Interesting

Executive summary

Docs

-

Code

-

Also change docs if applicable.

- -

Infrastructure

- - -

* I'm only willing to provide conversion.hpp FP support. Providing
-types that mimic FP types is far beyond my knowledge of how to deal
-with floating point's notorious arithmetic issues.

-

Support IEEE754 format (32 bit, 64 bit) only.


Last revised: -17 December, 2014

+17 January, 2015

© Copyright Beman Dawes, 2012

Distributed under the Boost Software License, Version 1.0. See www.boost.org/LICENSE_1_0.txt