![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
Endian LibraryBoost , ,
|
Endian Home Функции преобразования Арифметические типы Буферные типы Выбор подхода |
Повышаю. Endian предоставляет возможности для манипулированияэндианностьюцелых чисел и определяемых пользователем типов.
Рассмотрим следующий код:
int16_t i = 0x0102; FILE * file = fopen("test.bin", "wb"); // binary file! fwrite(&i, sizeof(int16_t), 1, file); fclose(file);
На OS X, Linux или системах Windows с процессором Intel, шестнадцатеричный сброс "теста. bin" выходной файл производит:
<
0201
>
На системах OS X с процессором PowerPC, или системах Solaris с процессором SPARC, шестнадцатеричный сброс "теста. bin" выходной файл производит:
<
0102
>
Здесь происходит то, что процессоры Intel сначала заказывают байты целого числа с наименее значимым байтом, в то время как процессоры SPARC сначала размещают самый значимый байт. Некоторые процессоры, такие как PowerPC, позволяют операционной системе выбирать, какой заказ применяется.
Наиболее значимый байт-первый порядок традиционно называется "большой эндиан" заказ и наименее значимый байт-первый традиционно называется "маленький эндиан" заказ. Название происходит от сатирического романаДжонатана Свифта.Путешествия Гулливера, где соперничающие царства открывали свои яйца в мягком варе на разных концах.
См. статью ВикипедииЭндианностьдля широкого обсуждения эндианности.
Программисты обычно могут игнорировать эндианность, за исключением случаев, когда они читают свалку ядра на малоэндианных системах. Но программистам приходится иметь дело с эндианностью при обмене двоичными целыми числами и двоичными значениями плавающей точки между компьютерными системами с различной эндианностью, будь то физическая передача файлов или по сети. Программисты также могут использовать библиотеку при минимизации внутренних или внешних размеров данных.
Повышаю. Эндиан предлагает три различных подхода к борьбе с эндианностью. Все три подхода поддерживают целые числа и типы пользовательских определений (UDT).
Каждый подход имеет долгую историю успешного использования, и каждый подход имеет случаи использования, когда он предпочтительнее других подходов.
Функции преобразования Эндиана-Приложение использует встроенные целочисленные типы для удержания значений и вызывает предоставленные функции преобразования для преобразования байтового порядка по мере необходимости. Поставляются как мутирующие, так и немутирующие конверсии, и каждый из них поставляется в безусловных и условных вариантах.
Типы буферов Эндиана-Приложение использует предоставленные эндиановые типы буферов для удержания значений и явно преобразует в встроенные целые типы и из них. Предоставляются буферные размеры 8, 16, 24, 32, 40, 48, 56 и 64 бит (т.е. 1, 2, 3, 4, 5, 6, 7 и 8 байт). Неупорядоченные целочисленные типы буферов предусмотрены для всех размеров, а выровненные типы буферов предусмотрены для 16, 32 и 64-разрядных размеров. Предоставленные конкретные типы представляют собой типографские теги для шаблона общего класса, которые могут использоваться непосредственно для менее распространенных вариантов использования.
Эндийские арифметические типы-Приложение использует предоставленные эндиановые типы арифметики, которые обеспечивают те же операции, что и встроенные типы арифметики C++. Все преобразования являются неявными. Предоставляются арифметические размеры 8, 16, 24, 32, 40, 48, 56 и 64 бит (т.е. 1, 2, 3, 4, 5, 6, 7 и 8 байт). Невыровненные целые типы предусмотрены для всех размеров, а выровненные арифметические типы предусмотрены для 16, 32 и 64-битных размеров. Предоставляемые конкретные типы представляют собой типографские теги для шаблона общего класса, которые могут использоваться непосредственно в общем коде для менее распространенных случаев использования.
Boost Endian - это библиотека только для заголовков. Функции C++11, влияющие на интерфейсы, такие как<noexcept
>, используются только при наличии. См.Поддержка C++03 для функций C++11для деталей.
Этот раздел был перемещен на его собственную страницуВыбор подхода.
Большинство компиляторов, включая GCC, Clang и Visual C++, предоставляют встроенную поддержку для байт-своппинга. Библиотека Endian использует эти внутренние элементы, поскольку они могут привести к меньшему и более быстрому генерируемому коду, особенно для оптимизированных сборок.
Определение макроса<BOOST_ENDIAN_NO_INTRINSICS
>будет подавлять использование сущностей. Это полезно, когда компилятор не имеет внутренней поддержки или не может найти соответствующий заголовок, возможно, потому, что он является более старым релизом или имеет очень ограниченные библиотеки поддержки.
Макро<BOOST_ENDIAN_INTRINSIC_MSG
>определяется как<"no byte swap intrinsics"
>или строка, описывающая конкретный набор используемых внутренних элементов. Это полезно для устранения недостающих свойств как источника проблем с производительностью.
Рассмотрим эту проблему:
Add 100 to a big endian value in a file, then write the result to a file | |
Подход эндианского арифметического типа | Подход эндиановой функции преобразования |
big_int32_at x; ... read into x from a file ... x += 100; ... write x to a file ... |
<int32_t x; ... read into x from a file ... big_to_native_inplace(x); x += 100; native_to_big_inplace(x); ... write x to a file ...> |
Не будет никакой разницы в производительности между двумя подходами в оптимизированных сборках, независимо от нативной эндианности машины.Это и 39; потому что оптимизация компиляторов будет генерировать точно такой же код для каждого. Этот вывод был подтвержден изучением сгенерированного кода сборки для GCC и Visual C++. Кроме того, время, затрачиваемое на выполнение ввода/вывода, определяет скорость этого приложения.
Теперь рассмотрим немного другую проблему:
Add a million values to a big endian value in a file, then write the result to a file | |
Подход эндианского арифметического типа | Подход эндиановой функции преобразования |
big_int32_at x; ... read into x from a file ... for (int32_t i = 0; i < 1000000; ++i) x += i; ... write x to a file ... |
<int32_t x; ... read into x from a file ... big_to_native_inplace(x); for (int32_t i = 0; i < 1000000; ++i) x += i; native_to_big_inplace(x); ... write x to a file ...> |
С эндианским арифметическим подходом на маленьких эндианских платформах происходит неявное преобразование из и обратно в большой эндиан. При подходе к функции конверсии Endian пользователь гарантирует, что конверсии выполняются вне цикла, поэтому код может работать быстрее на небольших эндиан-платформах.
Эти тесты были запущены против сборок релиза примерно в 2012 году 4-ядерного маленького эндиана X64 Intel Core i5-3570K CPU @ 3,40 ГГц под Windows 7.
Пещерный пылесос: Таймер Windows CPU имеет очень высокую гранулярность. Повторные пробежки одних и тех же тестов часто дают значительно разные результаты.
См.test/loop_time_test.cppдля фактического кода иbenchmark/Jamfile.v2для настройки сборки.
GNU C++ version 4.8.2 on Linux virtual machine | |||||
Iterations: 10'000'000'000, Intrinsics: __builtin_bswap16, etc. | |||||
Проверка | Endian arithmetic type |
Endian conversion function |
|||
16-битный выровненный большой эндиан | 8.46 s | 5.28 s | |||
16-битный маленький эндиан | 5.28 s | 5.22 s | |||
32-битный выровненный большой эндиан | 8.40 s | 2.11 s | |||
32-битный маленький эндиан | 2.11 s | 2.10 s | |||
64-битный выровненный большой эндиан | 14.02 s | 3.10 s | |||
64-битный маленький эндиан | 3.00 s | 3.03 s |
Microsoft Visual C++ version 14.0 | |||||
Iterations: 10'000'000'000, Intrinsics: cstdlib _byteswap_ushort, etc. | |||||
Проверка | Endian arithmetic type |
Endian conversion function |
|||
16-битный выровненный большой эндиан | 8.27 s | 5.26 s | |||
16-битный маленький эндиан | 5.29 s | 5.32 s | |||
32-битный выровненный большой эндиан | 8.36 s | 5.24 s | |||
32-битный маленький эндиан | 5.24 s | 5.24 s | |||
64-битный выровненный большой эндиан | 13.65 s | 3.34 s | |||
64-битный маленький эндиан | 3.35 s | 2.73 s |
Только ли заголовок реализации?
Да.
Поддерживаются ли компиляторы C++03?
Да.
Использует ли реализация встроенный в байт-свопинг компилятора?
Да, если есть. Видишь?Внутренняя встроенная поддержка.
Зачем беспокоиться о эндианности?
Переносимость двоичных данных является основным вариантом использования.
Имеет ли эндианность какое-либо применение вне портативных двоичных файлов или сетевых форматов ввода/вывода?
Использование невыровненных целых типов с размером, адаптированным к потребностям приложения & # 39, является второстепенным использованием, которое сохраняет внутреннее или внешнее пространство памяти. Например, использование<
big_int40_buf_t
>или<big_int40_t
>в большом массиве экономит много места по сравнению с одним из 64-битных типов.
Зачем беспокоиться о двоичном I/O? Почему стоит использовать C++ Стандартные библиотечные вставки и экстракторы?
Форматы обмена данными часто определяют двоичные целочисленные данные.
Бинарные целочисленные данные меньше, поэтому I/O быстрее, а размеры файлов меньше. Передача между системами обходится дешевле.
Furthermore, binary integer data is of fixed size, and so fixed-size disk records are possible without padding, easing sorting and allowing random access.
Disadvantages, such as the inability to use text utilities on the resulting files, limit usefulness to applications where the binary I/O advantages are paramount.
Что лучше: большой или маленький?
Big-endian, как правило, предпочтительнее в сетевой среде и немного больше отраслевого стандарта, но Little-endian может быть предпочтительнее для приложений, которые работают в основном на x86, x86-64 и других процессорах Little-endian. СтатьяВикипедиядает больше плюсов и минусов.
Почему поддерживается только большая и маленькая родная эндианность?
Это единственные эндианские схемы, которые сегодня имеют какую-либо практическую ценность. PDP-11 и другие подходы среднего эндиана интересны, но не имеют отношения к сегодняшним разработчикам C++. То же самое относится и к архитектурам, которые позволяют переключать эндианность во время выполнения. Спецификациядля нативного заказабыла тщательно разработана, чтобы обеспечить поддержку таких заказов в будущем, если возникнет необходимость. Спасибо Говарду Хиннанту за предложение.
Почему существуют буферные и арифметические типы?
Конверсии в буферных типах являются явными. Преобразования в арифметических типах неявны. Это фундаментальное различие является преднамеренной особенностью дизайна, которая была бы потеряна, если бы иерархия наследования была разрушена.
Оригинальный дизайн предусматривал только арифметические типы. Типы буферов были запрошены во время официального рассмотрения теми, кто желает получить полный контроль над конверсией. Они также полагали, что буферные типы с меньшей вероятностью будут неправильно использоваться программистами технического обслуживания, не знакомыми с последствиями выполнения множества целочисленных операций на эндиановых арифметических целочисленных типах.
Что получается при использовании буферных типов, а не только при использовании арифметических типов?
Гарантия того, что скрытые преобразования не выполняются. Это имеет первостепенное значение для пользователей, заинтересованных в достижении максимальной скорости.
Всегда простое использование типов арифметики отлично подходит для других пользователей. Когда необходимо обеспечить максимальную скорость, арифметические типы могут использоваться в тех же шаблонах проектирования или идиомах, которые будут использоваться для буферных типов, в результате чего один и тот же код генерируется для обоих типов.
Каковы ограничения целочисленной поддержки?
Испытания проводились только на машинах, которые используют арифметику комплемента. Функции преобразования Endian поддерживают только 16, 32 и 64-разрядные целые числа. Эндиановые типы поддерживают только 8, 16, 24, 32, 40, 48, 56 и 64-битные невыровненные целые числа, а 8, 16, 32 и 64-битные выровненные целые числа.
Почему нет поддержки плавающей точки?
Была предпринята попытка поддержки четырехбайтной<
float
>и восьмибайтной<double
>точек, ограниченнойIEEE 754(также известной как ISO/IEC/IEEE 60559) плавающей точкой и далее ограниченной системами, в которых плавающая точка эндианности не отличается от целочисленной эндианности.Даже с этими ограничениями поддержка типов с плавающей запятой не была надежной и была удалена. Например, простое изменение эндианности числа с плавающей точкой может привести к сигнализации-NAN. Для всех практических целей двоичная сериализация и эндианность для целых чисел являются одной и той же проблемой. Это не относится к числам с плавающей запятой, поэтому интерфейсы и форматы двоичной сериализации для с плавающей запятой плохо вписываются в библиотеку на основе эндиана.
Библиотека была переработана сверху донизу, чтобы учесть изменения, запрошенные во время официального обзора. См.Мини-обзорстраницы для деталей.
boost/endian/endian.hpp
был переименован в
boost/endian/arithmetic.hpp
. Добавлены заголовкиboost/endian/conversion.hpp
иboost/endian/buffers.hpp
. Соответственно были изменены имена файлов инфраструктуры._t
, но имена псевдонимов выровненного типа теперь имеют суффикс_at
.endian_reverse()
перегрузкиint8_t
и
uint8_t
были добавлены для улучшенной общности. (Пьер Тэлбот)endian_reverse_inplace()
на
endian_reverse_inplace()
endian_reverse_inplace()
. (Пьер Тэлбот)noexcept
. Компиляторы C++03 все еще поддерживаются.До официального релиза Boost шаблон класса<
endian_arithmetic
>использовался в течение десятилетия или более с той же функциональностью, но под названием<endian
>. Другие названия также изменились в официальном релизе. Если макро<BOOST_ENDIAN_DEPRECATED_NAMES
>определено, то те старые, ныне обесцененные имена все еще поддерживаются. Однако имя шаблона класса<endian
>предоставляется только для компиляторов, поддерживающих псевдонимы шаблонов C++11. Для компиляторов C++03 название должно быть изменено на<endian_arithmetic
>.
Для поддержки обратной совместимости заголовка, устаревший заголовок<boost/endian/endian.hpp
>перенаправляется на<boost/endian/arithmetic.hpp
>. Для этого требуется<
BOOST_ENDIAN_DEPRECATED_NAMES
>. Он должен использоваться только при переходе к официальному выпуску библиотеки, поскольку он будет удален в будущем выпуске.
Функция C++11 | Работа с компиляторами C++03 |
Охваченные числа | Использует заголовок<
boost/core/scoped_enum.hpp >для эмуляции C++11. |
<noexcept > |
Использует макрос BOOST_NOEXCEPT, который определяется как нуль для компиляторов, не поддерживающих эту функцию C++11. |
C++11 PODsN2342 | Использует компиляторы C++03, которые расслабляют правила POD C++03, но см. Ограниченияздесьиздесь. Также см. макросы для явного управления PODздесьиздесь. |
Стандартизация.План состоит в том, чтобы придать импульс. Эндиан в комитет по стандартам C++ для возможного включения в Техническую спецификацию или сам стандарт C++.
Специализация<numeric_limits
>.Роджер Ли попросил, чтобы все<boost::endian
>типов предоставили<numeric_limits
>специализации. См.GitHub issue 4.
Поддержка буфера символов.Петр Димов в ходе мини-обзора указал, что получение и установка базовых арифметических типов (или<<cstdint>
>эквивалентов) из/в смещение в массив неподписанного угля является общей необходимостью. См.Boost.Endian mini-review posting.
Обнаружение вне зоны действия.Петр Димов в ходе мини-обзора предположил, что желательно сделать исключение из буферных значений. См. конецэтой публикациии последующие ответы.
Комментарии и предложения были получены от Аддера, Бенаки Мурти, Кристофера Колхоффа, Клиффа Грина, Даниэля Джеймса, Дэйва Хандли, Дженнаро Прото, Гордона Деретта, Гордона Вудхула, головокружения, Хартмута Кайзера, Говарда Хиннана, Джейсона Ньютона, Джеффа Флинна, Джереми Майтина-Шепарда, Джона Фило, Джона Мэддока, Кима Барретта, Марша Рэя, Мартина Боннера, Матиаса Капелетто, Матиаса Капелетто, Нейла Мэйхью, Невина Либера, Олафа ван дер Спека, Пола Бристоу, Питера Димова, Пьера Эндекота, Фила Беннефолла, Пири Джахколы, Рене Риверы, Роберта Стюарта, Роланда Ли, Роланда Шварца, Себастьяна Редла, Тима Блехмана, Тима Прошу прощения, если кого-то пропустили.
Последнее изменение:05 Апрель 201605 April, 2016[ORIG_END] -->
© Copyright Beman Dawes, 2011, 2013
Распространяется в соответствии с Лицензией на программное обеспечение Boost, версия 1.0. См.www.boost.org/ LICENSE_1_0.txt
Статья Endian Library раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: ::
реклама |