diff --git a/doc/index.html b/doc/index.html index 85a338f..1ae47bd 100644 --- a/doc/index.html +++ b/doc/index.html @@ -39,6 +39,11 @@ Abstract
Introduction to endianness
Introduction to the Boost.Endian library
+ Choosing approaches
+ Performance
+    Timings
+    Conclusions
+ FAQ
Acknowledgements @@ -51,18 +56,19 @@ <boost/endian/types.hpp> +

Abstract

-

Boost.Endian provides two facilities to manipulate the byte ordering of integers.

+

Boost.Endian provides facilities to manipulate the endianness of integers, +floating point, and user defined data.

@@ -87,9 +93,9 @@ output file produces:

0102

-

What's happening here is that Intel CPU's order the bytes of an integer with -the least-significant byte first, while SPARC CPU's place the most-significant -byte first. Some CPU's, such as the PowerPC, allow the operating system to +

What's happening here is that Intel CPUs order the bytes of an integer with +the least-significant byte first, while SPARC CPUs place the most-significant +byte first. Some CPUs, such as the PowerPC, allow the operating system to choose which ordering applies.

Most-significant-byte-first ordering is traditionally called "big endian" ordering and the least-significant-byte-first is traditionally called @@ -102,29 +108,33 @@ at different ends.

See the Wikipedia's Endianness article for an extensive discussion of endianness.

-

Except for reading a core dump on little-endian systems, most programmers can -ignore endianness. But when exchanging binary integers and binary floating point -values between computer systems with differing endianness, whether by physical file transfer or over a network, programmers have to deal with endianness -in their code.

+

Most programmers can ignore endianness, except perhaps for reading a core +dump on little-endian systems. Programmers have to deal with endianness in their +code when exchanging binary integers and binary floating point +values between computer systems with differing endianness, whether by physical file transfer or over a network, +.

Introduction to the Boost.Endian library

-

The Boost.Endian library provides two facilities for dealing with endianness.

+

The Boost.Endian library provides two different approaches to dealing with +integer endianness. Both approaches support integers, floating point types +except  long double, and user defined types (UDTs).

-

The library provides two approaches to dealing with integer endianness:

+

Each approach has a long history of successful use, and each approach has use +cases where it is superior to the other approach.

-

Endian conversions - The application -uses the built-in integer and floating point types, and calls the provided -conversion functions to convert byte ordering as needed. Both mutating and -non-mutating conversions are supplied, and each comes in unconditional and -conditional variants. Type long double is not currently supported.

-

Endian types - The application uses the provided endian types which mimic the -built-in integer types. For example, big32_t or little64_t. Types with lengths of -1-8 bytes are supported, rather than just  2, 4, and 8 bytes. There are no alignment -requirements. Floating point types are not currently supported.

+built-in integer types. For example, big_int32_t or little_float64_t. +Integer types with lengths of 1 through 8 bytes are supported, rather than just +2, 4, and 8 byte integers. The types may be aligned or unaligned.

+ +

Endian conversion functions - The +application uses the built-in integer and floating point types, and calls the +provided conversion functions to convert byte ordering as needed. Both mutating +and non-mutating conversions are supplied, and each comes in unconditional and +conditional variants.

@@ -133,16 +143,18 @@ requirements. Floating point types are not currently supported.

Choosing between endian types and endian conversion functions

-

Which approach is best for dealing with endianness depends on -application concerns.

+

Which approach is better for dealing with endianness depends on +application needs.

- - + +
Needs that favor one approach over the other
Endian typesEndian conversion functionsEndian types are better with + these needsEndian conversion functions are better + with these needs
@@ -188,6 +200,10 @@ application concerns.

Consider this problem:

+ + + @@ -223,13 +239,18 @@ big_endian(x);
+

Example 1

Add 100 to a big endian value in a file, then write the result to a file
-

There will be no performance difference between the two approaches, -regardless of the native endianness of the machine. Optimizing compilers will likely -generate exactly the same code for both.

+

There will be no performance difference between the two approaches, +regardless of the native endianness of the machine. Optimizing compilers will likely +generate exactly the same code for both. That conclusion was confirmed by +studying the generated assembly code.

Now consider a slightly different problem: 

+ + + @@ -268,25 +289,14 @@ big_endian(x);
+

Example 2

Add a million values to a big endian value in a file, then write the result to a file
-

There may or may not be a considerable performance difference, depending -on the endianness of the machine. If machine endianness differs from the -desired endianness, the Endian type approach must do the byte reversal a million -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.

- -

If compiler byte swap intrinsics are not available, any timing differences -will be magnified. Byte swap intrinsics are not available on some older -compilers and on some machine architectures, such as pre-486 X86 CPUs.

- -

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

- -

Timing tests

+

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

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 setup. @@ -376,6 +386,44 @@ setup.

+

Conclusions

+ +

When program logic dictates the same number of conversions for both Endian +integer approach and Endian conversion function approach (example +1):

+ +
+ +

There will be no performance difference between the two approaches, +regardless of the native endianness of the machine. Optimizing compilers will likely +generate exactly the same code for both. This conclusion was confirmed by +studying the generated assembly code.

+ +
+ +

When program logic dictates many more conversions for the Endian integer +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 type 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 available has little +impact. Byte swap intrinsics are not available on some older +compilers and on some machine architectures, such as pre-486 X86 CPUs.

+ +

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

+ +
+ +

Overall FAQ

Why bother with endianness?

diff --git a/test/loop_time_test.cpp b/test/loop_time_test.cpp index 7a3e32c..6938e0c 100644 --- a/test/loop_time_test.cpp +++ b/test/loop_time_test.cpp @@ -9,7 +9,7 @@ #define _SCL_SECURE_NO_WARNINGS -#define BOOST_ENDIAN_NO_INTRINSICS +//#define BOOST_ENDIAN_NO_INTRINSICS //#define BOOST_ENDIAN_LOG #include @@ -223,7 +223,7 @@ int cpp_main(int argc, char* argv[]) "Endian
conversion
function
\n" "\n" ; - + test_big_int16(); test_little_int16(); test_big_int16un();