diff --git a/index.html b/index.html index a134079..b15f712 100644 --- a/index.html +++ b/index.html @@ -259,10 +259,10 @@ big_endian(x); -

There will be no performance difference between the two approaches, -regardless of the native endianness of the machine. Optimizing compilers will likely +

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.

+studying the generated assembly code for GCC and Visual C++.

Now consider a slightly different problem: 

@@ -377,55 +377,42 @@ setup. Endian
type
Endian
conversion
function
-16-bit aligned big endian2.18 s0.83 s -16-bit aligned little endian0.81 s0.83 s -16-bit unaligned big endian1.64 s0.83 s -16-bit unaligned little endian1.64 s0.83 s -32-bit aligned big endian0.83 s0.81 s -32-bit aligned little endian0.83 s0.81 s -32-bit unaligned big endian3.01 s0.83 s -32-bit unaligned little endian3.01 s0.81 s -64-bit aligned big endian1.09 s1.05 s -64-bit aligned little endian0.83 s1.03 s -64-bit unaligned big endian12.64 s1.01 s -64-bit unaligned little endian8.41 s0.83 s +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 Case Endian
type
Endian
conversion
function
-16-bit aligned big endian0.84 s0.81 s -16-bit aligned little endian0.83 s0.81 s -16-bit unaligned big endian1.65 s0.81 s -16-bit unaligned little endian1.65 s0.83 s -32-bit aligned big endian3.46 s0.83 s -32-bit aligned little endian0.81 s0.83 s -32-bit unaligned big endian3.01 s0.81 s -32-bit unaligned little endian3.01 s0.81 s -64-bit aligned big endian10.50 s0.83 s -64-bit aligned little endian0.83 s0.97 s -64-bit unaligned big endian12.62 s0.81 s -64-bit unaligned little endian8.42 s0.81 s +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

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):

@@ -587,7 +574,7 @@ Tim Blechmann, Tim Moore, tymofey, Tomas Puverle, Vincente Botet, Yuval Ronen and Vitaly Budovski,.


Last revised: -28 May, 2013

+30 May, 2013

© 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/types.html b/types.html index ed6c2f7..18720a2 100644 --- a/types.html +++ b/types.html @@ -227,98 +227,98 @@ conventions for common use cases:

Alignment - big_intn_t + big_align_intn_t big signed 16,32,64 yes - big_uintn_t + big_align_uintn_t big unsigned 16,32,64 yes + + big_align_floatn_t + big + signed + 32,64 + yes + + + little_align_intn_t + little + signed + 16,32,64 + yes + + + little_align_uintn_t + little + unsigned + 16,32,64 + yes + + + little_align_floatn_t + little + signed + 32,64 + yes + + + big_intn_t + big + signed + 8,16,24,32,40,48,56,64 + no + + + big_uintn_t + big + unsigned + 8,16,24,32,40,48,56,64 + no + big_floatn_t big signed 32,64 - yes + no - little_intn_t + little_intn_t little signed - 16,32,64 - yes + 8,16,24,32,40,48,56,64 + no - little_uintn_t + little_uintn_t little unsigned - 16,32,64 - yes + 8,16,24,32,40,48,56,64 + no little_floatn_t little signed 32,64 - yes - - - big_intnun_t - big - signed - 8,16,24,32,40,48,56,64 no - big_uintnun_t - big - unsigned - 8,16,24,32,40,48,56,64 - no - - - big_floatnun_t - big - signed - 32,64 - no - - - little_intnun_t - little - signed - 8,16,24,32,40,48,56,64 - no - - - little_uintnun_t - little - unsigned - 8,16,24,32,40,48,56,64 - no - - - little_floatnun_t - little - signed - 32,64 - no - - - native_intnun_t + native_intn_t native signed 8,16,24,32,40,48,56,64 no - native_uintnun_t + native_uintn_t native unsigned 8,16,24,32,40,48,56,64 @@ -332,8 +332,9 @@ memory, files, and network transmissions.

Warning: Code that uses aligned types is possibly non-portable because alignment requirements vary between hardware architectures and because alignment may be -affected by compiler switches or pragmas. Furthermore, aligned types -are only available on architectures with 16, 32, and 64-bit integer types.

+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 have identical functionality. They are provided to improve code readability and searchability.

@@ -386,103 +387,103 @@ usual operations on integers are supplied.

endian operator--(endian& x, int) noexcept; }; - typedef endian<order::big, float, 32, align::yes> big_float32_t; - typedef endian<order::big, double, 64, align::yes> big_float64_t; - - // aligned little endian floating point types - typedef endian<order::little, float, 32, align::yes> little_float32_t; - typedef endian<order::little, double, 64, align::yes> little_float64_t; - - // unaligned big endian floating point types - typedef endian<order::big, float, 32, align::no> big_float32un_t; - typedef endian<order::big, double, 64, align::no> big_float64un_t; + typedef endian<order::big, float, 32, align::yes> big_align_float32_t; + typedef endian<order::big, double, 64, align::yes> big_align_float64_t; + + // aligned little endian floating point types + typedef endian<order::little, float, 32, align::yes> little_align_float32_t; + typedef endian<order::little, double, 64, align::yes> little_align_float64_t; + + // unaligned big endian floating point types + typedef endian<order::big, float, 32, align::no> big_float32un_t; + typedef endian<order::big, double, 64, align::no> big_float64un_t; // unaligned little endian floating point types - typedef endian<order::little, float, 32, align::no> little_float32un_t; - typedef endian<order::little, double, 64, align::no> little_float64un_t; + typedef endian<order::little, float, 32, align::no> little_float32un_t; + typedef endian<order::little, double, 64, align::no> little_float64un_t; // aligned big endian signed integer types - typedef endian<order::big, int16_t, 16, align::yes> big_int16_t; - typedef endian<order::big, int32_t, 32, align::yes> big_int32_t; - typedef endian<order::big, int64_t, 64, align::yes> big_int64_t; - - // aligned big endian unsigned integer types - typedef endian<order::big, uint16_t, 16, align::yes> big_uint16_t; - typedef endian<order::big, uint32_t, 32, align::yes> big_uint32_t; - typedef endian<order::big, uint64_t, 64, align::yes> big_uint64_t; - - // aligned little endian signed integer types - typedef endian<order::little, int16_t, 16, align::yes> little_int16_t; - typedef endian<order::little, int32_t, 32, align::yes> little_int32_t; - typedef endian<order::little, int64_t, 64, align::yes> little_int64_t; - - // aligned little endian unsigned integer types - typedef endian<order::little, uint16_t, 16, align::yes> little_uint16_t; - typedef endian<order::little, uint32_t, 32, align::yes> little_uint32_t; - typedef endian<order::little, uint64_t, 64, align::yes> little_uint64_t; - - // aligned native endian typedefs are not provided because - // <cstdint> types are superior for this use case + typedef endian<order::big, int16_t, 16, align::yes> big_align_int16_t; + typedef endian<order::big, int32_t, 32, align::yes> big_align_int32_t; + typedef endian<order::big, int64_t, 64, align::yes> big_align_int64_t; + + // aligned big endian unsigned integer types + typedef endian<order::big, uint16_t, 16, align::yes> big_align_uint16_t; + typedef endian<order::big, uint32_t, 32, align::yes> big_align_uint32_t; + typedef endian<order::big, uint64_t, 64, align::yes> big_align_uint64_t; + + // aligned little endian signed integer types + typedef endian<order::little, int16_t, 16, align::yes> little_align_int16_t; + typedef endian<order::little, int32_t, 32, align::yes> little_align_int32_t; + typedef endian<order::little, int64_t, 64, align::yes> little_align_int64_t; + + // aligned little endian unsigned integer types + typedef endian<order::little, uint16_t, 16, align::yes> little_align_uint16_t; + typedef endian<order::little, uint32_t, 32, align::yes> little_align_uint32_t; + typedef endian<order::little, uint64_t, 64, align::yes> little_align_uint64_t; + + // aligned native endian typedefs are not provided because + // <cstdint> types are superior for this use case // unaligned big endian signed integer types - typedef endian<order::big, int_least8_t, 8> big_int8un_t; - typedef endian<order::big, int_least16_t, 16> big_int16un_t; - typedef endian<order::big, int_least32_t, 24> big_int24un_t; - typedef endian<order::big, int_least32_t, 32> big_int32un_t; - typedef endian<order::big, int_least64_t, 40> big_int40un_t; - typedef endian<order::big, int_least64_t, 48> big_int48un_t; - typedef endian<order::big, int_least64_t, 56> big_int56un_t; - typedef endian<order::big, int_least64_t, 64> big_int64un_t; + typedef endian<order::big, int_least8_t, 8> big_int8_t; + typedef endian<order::big, int_least16_t, 16> big_int16_t; + typedef endian<order::big, int_least32_t, 24> big_int24_t; + typedef endian<order::big, int_least32_t, 32> big_int32_t; + typedef endian<order::big, int_least64_t, 40> big_int40_t; + typedef endian<order::big, int_least64_t, 48> big_int48_t; + typedef endian<order::big, int_least64_t, 56> big_int56_t; + typedef endian<order::big, int_least64_t, 64> big_int64_t; // unaligned big endian unsigned integer types - typedef endian<order::big, uint_least8_t, 8> big_uint8un_t; - typedef endian<order::big, uint_least16_t, 16> big_uint16un_t; - typedef endian<order::big, uint_least32_t, 24> big_uint24un_t; - typedef endian<order::big, uint_least32_t, 32> big_uint32un_t; - typedef endian<order::big, uint_least64_t, 40> big_uint40un_t; - typedef endian<order::big, uint_least64_t, 48> big_uint48un_t; - typedef endian<order::big, uint_least64_t, 56> big_uint56un_t; - typedef endian<order::big, uint_least64_t, 64> big_uint64un_t; + typedef endian<order::big, uint_least8_t, 8> big_uint8_t; + typedef endian<order::big, uint_least16_t, 16> big_uint16_t; + typedef endian<order::big, uint_least32_t, 24> big_uint24_t; + typedef endian<order::big, uint_least32_t, 32> big_uint32_t; + typedef endian<order::big, uint_least64_t, 40> big_uint40_t; + typedef endian<order::big, uint_least64_t, 48> big_uint48_t; + typedef endian<order::big, uint_least64_t, 56> big_uint56_t; + typedef endian<order::big, uint_least64_t, 64> big_uint64_t; // unaligned little endian signed integer types - typedef endian<order::little, int_least8_t, 8> little_int8un_t; - typedef endian<order::little, int_least16_t, 16> little_int16un_t; - typedef endian<order::little, int_least32_t, 24> little_int24un_t; - typedef endian<order::little, int_least32_t, 32> little_int32un_t; - typedef endian<order::little, int_least64_t, 40> little_int40un_t; - typedef endian<order::little, int_least64_t, 48> little_int48un_t; - typedef endian<order::little, int_least64_t, 56> little_int56un_t; - typedef endian<order::little, int_least64_t, 64> little_int64un_t; + typedef endian<order::little, int_least8_t, 8> little_int8_t; + typedef endian<order::little, int_least16_t, 16> little_int16_t; + typedef endian<order::little, int_least32_t, 24> little_int24_t; + typedef endian<order::little, int_least32_t, 32> little_int32_t; + typedef endian<order::little, int_least64_t, 40> little_int40_t; + typedef endian<order::little, int_least64_t, 48> little_int48_t; + typedef endian<order::little, int_least64_t, 56> little_int56_t; + typedef endian<order::little, int_least64_t, 64> little_int64_t; // unaligned little endian unsigned integer types - typedef endian<order::little, uint_least8_t, 8> little_uint8un_t; - typedef endian<order::little, uint_least16_t, 16> little_uint16un_t; - typedef endian<order::little, uint_least32_t, 24> little_uint24un_t; - typedef endian<order::little, uint_least32_t, 32> little_uint32un_t; - typedef endian<order::little, uint_least64_t, 40> little_uint40un_t; - typedef endian<order::little, uint_least64_t, 48> little_uint48un_t; - typedef endian<order::little, uint_least64_t, 56> little_uint56un_t; - typedef endian<order::little, uint_least64_t, 64> little_uint64un_t; + typedef endian<order::little, uint_least8_t, 8> little_uint8_t; + typedef endian<order::little, uint_least16_t, 16> little_uint16_t; + typedef endian<order::little, uint_least32_t, 24> little_uint24_t; + typedef endian<order::little, uint_least32_t, 32> little_uint32_t; + typedef endian<order::little, uint_least64_t, 40> little_uint40_t; + typedef endian<order::little, uint_least64_t, 48> little_uint48_t; + typedef endian<order::little, uint_least64_t, 56> little_uint56_t; + typedef endian<order::little, uint_least64_t, 64> little_uint64_t; // unaligned native endian signed integer types - typedef endian<order::native, int_least8_t, 8> native_int8un_t; - typedef endian<order::native, int_least16_t, 16> native_int16un_t; - typedef endian<order::native, int_least32_t, 24> native_int24un_t; - typedef endian<order::native, int_least32_t, 32> native_int32un_t; - typedef endian<order::native, int_least64_t, 40> native_int40un_t; - typedef endian<order::native, int_least64_t, 48> native_int48un_t; - typedef endian<order::native, int_least64_t, 56> native_int56un_t; - typedef endian<order::native, int_least64_t, 64> native_int64un_t; + typedef endian<order::native, int_least8_t, 8> native_int8_t; + typedef endian<order::native, int_least16_t, 16> native_int16_t; + typedef endian<order::native, int_least32_t, 24> native_int24_t; + typedef endian<order::native, int_least32_t, 32> native_int32_t; + typedef endian<order::native, int_least64_t, 40> native_int40_t; + typedef endian<order::native, int_least64_t, 48> native_int48_t; + typedef endian<order::native, int_least64_t, 56> native_int56_t; + typedef endian<order::native, int_least64_t, 64> native_int64_t; // unaligned native endian unsigned integer types - typedef endian<order::native, uint_least8_t, 8> native_uint8un_t; - typedef endian<order::native, uint_least16_t, 16> native_uint16un_t; - typedef endian<order::native, uint_least32_t, 24> native_uint24un_t; - typedef endian<order::native, uint_least32_t, 32> native_uint32un_t; - typedef endian<order::native, uint_least64_t, 40> native_uint40un_t; - typedef endian<order::native, uint_least64_t, 48> native_uint48un_t; - typedef endian<order::native, uint_least64_t, 56> native_uint56un_t; - typedef endian<order::native, uint_least64_t, 64> native_uint64un_t; + typedef endian<order::native, uint_least8_t, 8> native_uint8_t; + typedef endian<order::native, uint_least16_t, 16> native_uint16_t; + typedef endian<order::native, uint_least32_t, 24> native_uint24_t; + typedef endian<order::native, uint_least32_t, 32> native_uint32_t; + typedef endian<order::native, uint_least64_t, 40> native_uint40_t; + typedef endian<order::native, uint_least64_t, 48> native_uint48_t; + typedef endian<order::native, uint_least64_t, 56> native_uint56_t; + typedef endian<order::native, uint_least64_t, 64> native_uint64_t; } // namespace endian } // namespace boost @@ -616,7 +617,7 @@ differs from endian representation size. Vicente Botet and other reviewers suggested supporting floating point types.


Last revised: -29 May, 2013

+31 August, 2013

© Copyright Beman Dawes, 2006-2009, 2013

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