促进。Endian提供了操作端序整数和用户定义的类型。
- 支持三种结束方式。每个都有一个成功使用的悠久历史,每种方法都有其使用案例优先于其他方法。
- 主要用途:
- 数据可移植性。Endian库支持通过外部媒体或网络传输进行二进制数据交换,不考虑平台端性。
- 程序可移植性。基于POSIX和基于Windows的操作系统传统上为库提供执行endian转换的不可移植函数。至少有四个常用的不兼容的函数集。Endian库是可跨所有C++平台移植。
- 次要用途:通过不受支持的大小和/或对齐最小化数据大小标准C++整数类型。
考虑以下代码:
int16_t i=0x0102;FILE*FILE=fopen(“test.bin”,“wb”);//二进制文件!fwrite(&i,sizeof(int16_t),1,文件);fclose(文件);
在具有Intel CPU的OS X、Linux或Windows系统上,十六进制转储“test.bin”输出文件生成:
0201
在具有PowerPC CPU的OS X系统上,或具有SPARC CPU的Solaris系统上,“test.bin”的十六进制转储输出文件生成:
0102
这里发生的情况是,Intel CPU将整数的字节排序为最不重要的字节在前,而SPARC CPU最重要字节优先。一些CPU(如PowerPC)允许操作系统选择适用的顺序。
最重要的字节优先排序传统上称为“big-endian”排序和最低有效字节优先传统上称为“little-endian”排序。名称来源于乔纳森·斯威夫特的讽刺小说
格列佛游记在那里,敌对王国打开了他们的软蛋在不同的一端。
参见维基百科持久性文章用于关于结尾的广泛讨论。
程序员通常可以忽略尾数,除非在读取内核时倾倒在小型发动机系统上。但程序员在交换二进制整数和二进制浮点时必须处理结束性具有不同尾数的计算机系统之间的值,无论是通过物理文件传输还是通过网络传输。当最小化内部或外部数据大小是有利的。
介绍到助推器。Endian库
促进。Endian提供了三种不同的处理方法结局。这三种方法都支持整数和用户定义类型(UDT)。
每种方法都有很长的成功使用历史,并且每种方法均有其用途优先于其他方法的情况。
Endian转换函数-这个应用程序使用内置的整数类型来保存值,并调用提供了转换功能以根据需要转换字节排序。两者都在变异提供了非变异转换,每种转换都是无条件的条件变量。
Endian缓冲区类型-应用程序使用提供的endian缓冲区类型以保存值,并显式转换为内置整数类型或从内置整数类型转换。缓冲区大小为8、16、24、32、40、48、56和64位(即。提供了1、2、3、4、5、6、7和8字节)。未对齐的整数缓冲区类型为所有大小提供,为16、32和64位大小。提供的特定类型是泛型类的typedef可以直接用于不太常见的用例的模板。
Endian算术类型-这个应用程序使用提供的endian算术类型,它们提供相同的操作作为内置C++算法类型。所有转换都是隐式的。8、16、24、32、40、48、56和64位的算术大小(即1、2、3、4、5、,6、7和8字节)。为所有大小和对齐为16、32和64位大小提供算术类型。提供的特定类型是可以使用的泛型类模板的typedef对于不太常见的用例,直接在的通用代码中。
Boost Endian是一个仅限头部的库。C++11功能影响接口,例如无例外
,仅在可用时使用。请参见C++03对C++11功能的支持了解详细信息。
选择转换函数、缓冲区类型、,和算术类型
此部分已移至自己的位置选择方法第页。
大多数编译器,包括GCC、Clang和Visual C++,都提供了对字节交换内部函数的内置支持。Endian库在可用时使用这些内部函数,因为它们可能会生成更小、更快的代码,尤其是优化的生成。
定义宏BOOST_ENDIAN_NO_本质
将禁止使用内部结构。当编译器没有内部支持或找不到合适的标头,可能是因为它是较旧的版本或支持库非常有限。
宏BOOST_ENDIAN_INTRINSIC消息
定义为任何一个“无字节交换内部函数”
或描述正在使用的特定内部函数集。这有助于消除遗漏intrinsic是性能问题的根源。
考虑这个问题:
示例1 |
将100加到文件中的大端值,然后将结果到文件 |
Endian算术类型方法 |
Endian转换函数方法 |
大_ int32 _ at x;…从文件读入x。。。x+=100;…将x写入文件。。。
|
整数32_t x;…从文件读入x。。。big_to_native_inplace(x);x+=100;本地to_big_inplace(x);…将x写入文件。。。
|
两种方法在优化的构建,不管机器的本机端号如何。这是因为优化编译器将为每个编译器生成完全相同的代码。这一结论得到了研究为GCC和Visual C++生成的汇编代码。此外,时间花费在I/O上的时间将决定此应用程序的速度。
现在考虑一个稍微不同的问题:
示例2 |
将一百万个值添加到文件中的大端值,然后编写结果到文件 |
Endian算术类型方法 |
Endian转换函数方法 |
大_ int32 _ at x;…从文件读入x。。。对于(int32_ti=0;i<1000000;++i)x+=i;…将x写入文件。。。
|
整数32_t x;…正在从文件读取x。。。big_to_native_inplace(x);对于(int32_ti=0;i<1000000;++i)x+=i;本地to_big_inplace(x);…将x写入文件。。。
|
使用Endian算法方法,在little-Endian平台上,从然后返回到的隐式转换big-endian是在循环中完成的。使用Endian转换函数方法,用户已确保在循环外进行转换,因此代码可以在little-endian平台上运行得更快。
这些测试是在大约2012年4核little-endian X64 Intel core i5-3570K的发布版本上运行的Windows 7下CPU@3.40GHz。
注意:Windows CPU计时器具有很高的粒度。重复的相同测试的运行往往会产生截然不同的结果。
请参见测试/循环时间测试.cpp实际代码和基准/Jamfile.v2用于构建设置。
Linux虚拟上的GNU C++4.8.2版机器 |
迭代次数:10'000'000'000,内部函数:__builtin_bswap16等。 |
测试用例 |
字节序 算术 类型 |
字节序 转换 功能 |
16位对齐的大端 | 8.46秒 | 5.28秒 |
16位对齐小端 | 5.28秒 | 5.22秒 |
32位对齐的大尾数 | 8.40秒 | 2.11秒 |
32位对齐的小端 | 2.11秒 | 2.10秒 |
64位对齐的大端 | 14.02秒 | 3.10秒 |
64位对齐的小端 | 3.00秒 | 3.03秒 |
Microsoft Visual C++14.0版 |
迭代次数:10'000'000'000,内部函数:cstdlib_byteswap_ushort等。 |
测试用例 |
字节序 算术 类型 |
字节序 转换 功能 |
16位对齐的大端 | 8.27秒 | 5.26秒 |
16位对齐小端 | 5.29秒 | 5.32秒 |
32位对齐的大尾数 | 8.36秒 | 5.24秒 |
32位对齐的小端 | 5.24秒 | 5.24秒 |
64位对齐的大端 | 13.65秒 | 3.34秒 |
64位对齐的小端 | 3.35秒 | 2.73秒 |
只是实现头吗?
是的。
是否支持C++03编译器?
是的。
实现是否使用编译器内置的字节交换?
是的,如果有的话。请参见内置支持.
为什么要为结尾费心呢?
二进制数据可移植性是主要用例。
endianess在可移植二进制文件或网络之外有任何用途吗I/O格式?
使用大小根据应用程序的需求是一种次要的二次使用,可以节省内部或外部内存空间。对于示例,使用big_int40_buf_t大
或大_ int40_t
在一个与64位类型中的一种相比,大数组节省了大量空间。
为什么要费心二进制I/O?为什么不使用C++标准库流插入器和抽出器?
数据交换格式通常指定二进制整数数据。
二进制整数数据较小,因此I/O速度更快,文件大小也更大都较小。系统之间的传输成本较低。
此外,二进制整数数据大小固定,因此磁盘大小固定记录无需填充,便于排序并允许随机访问。
缺点,例如无法在结果文件,限制了二进制I/O优势是至高无上的。
大发动机和小发动机哪个更好?
在网络环境中,大公司往往是首选,而且有点更符合行业标准,但可能更倾向于使用小型发动机主要在x86、x86-64和其他小型计算机上运行的应用程序CPU的维基百科文章给出了更多的利弊。
为什么只支持大大小小的本机端接?
这些是目前唯一具有实用价值的endian方案。PDP-11型而其他中端方法则是有趣的稀奇之处但与当今的C++开发人员无关。同样适用于允许运行时末端切换的体系结构。这个本机规范订购经过精心设计,允许在未来,如果需要的话。感谢霍华德·希南特的建议。
为什么缓冲区和算术类型都存在?
缓冲区类型中的转换是显式的。算术中的转换类型是隐式的。这种基本的差异是经过深思熟虑的设计特点如果继承层次结构崩溃,这将丢失。
最初的设计只提供了算术类型。缓冲区类型为希望完全控制时间的人员在正式审查期间提出要求发生转换。他们还认为缓冲区类型不太可能被不熟悉对endian算术整数类型执行大量整数操作。
使用缓冲区类型而不是始终使用算术类型?
确保不执行隐藏转换。这是压倒一切的对于关注速度方面达到极限的用户来说很重要。
“总是只使用算术类型”对其他用户来说很好。当需要确保速度的极限,可以在用于缓冲区类型的相同设计模式或习惯用法,导致为这两种类型生成的代码相同。
整数支持有哪些限制?
测试仅限于在使用二的补码算法的机器上执行。恩迪安人转换函数仅支持16、32和64位对齐整数。这个endian类型仅支持8、16、24、32、40、48、56和64位未对齐整数,以及8、16、32和64位对齐整数。
为什么没有浮点支持?
试图支持四字节浮动
s和8字节双重的
s、 限于IEEE 754标准(同时称为ISO/IEC/IEEE 60559)浮点,进一步限于以下系统浮点尾数与整数相同结局。
即使有这些限制,也不支持浮点类型可靠并被移除。例如,只需反转浮点数可能导致信令NAN。出于所有实际目的,二进制序列化和整数的结束性是一个相同的问题。浮点数不是这样的,所以二进制序列化接口浮点的格式不适合基于endian的库。
该库从上到下进行了修改,以适应所要求的更改在正式审查期间。请参见迷你审查第页了解详细信息。
- 标题
升压/endian/endian.hpp
已重命名为boost/endian/arithmetic.hpp
.标题boost/endian/conversion.hpp
和boost/endian/buffers.hpp
已经补充。基础结构文件名已相应更改。
- endian算术类型别名已重命名,使用整数和浮点一致的命名模式,以及为endian缓冲区类型提供的一组一致的别名。
- 未对齐的类型别名仍具有
_t吨
后缀,但对齐类型别名现在有一个_在
后缀。。
endian_reverse()
的重载整数8_t
和单位8_t
已添加以改进通用性。(皮埃尔·塔尔博特)
- 的过载
endian_reverse_inplace()
已被替换为单个endian_reverse_inplace()
模板。(皮埃尔·塔尔博特)
- 对于允许未对齐加载和存储的X86和X64架构,未对齐的小端缓冲区和算术类型使用常规加载和当尺寸精确时进行存储。这使得未对齐的小端缓冲区和算术类型在这些体系结构上效率显著提高。(杰里米Maitin-Shepard)
- 影响界面的C++11功能,例如
无例外
,现在使用。C++03编译器仍然支持。
- 确认信息已更新。
在Boost正式发布之前,类模板尾数_算术
已使用十年或更长时间功能,但在名称下字节存储次序
。其他名称也已更改在官方发布中。如果宏BOOST_ENDIAN_DEPRECATED_NAMES公司
定义后,仍然支持那些现在已弃用的旧名称。然而类模板字节存储次序
仅为编译器提供名称支持C++11模板别名。对于C++03编译器,名称必须是已更改为尾数_算术
.
为了支持向后标头兼容性,不推荐使用标头升压/endian/endian.hpp
转发至boost/endian/arithmetic.hpp
。它需要BOOST_ENDIAN_DEPRECATED_NAMES公司
定义。它只能在以下情况下使用过渡到库的官方Boost版本,因为它将被删除在将来的版本中。
C++11功能 |
使用C++03编译器的操作 |
作用域枚举 |
使用页眉
促进/核心/范围_编号.马力 以模拟C++11作用域枚举。 |
无例外 |
使用BOOST_NOEXCEPT宏,该宏定义为对于不支持此C++11功能的编译器,为null。 |
C++11 POD(N2342型) |
利用C++03编译器放宽C++03 POD规则,但请参阅限制在这里和在这里。另请参阅宏以了解显式POD控制在这里和在这里. |
标准化。计划提交Boost。C++结束符技术规范或C++标准本身。
专业领域数字极限
.罗杰·利要求所有boost::endian
类型提供数字极限
专业化。请参见GitHub问题4.
字符缓冲区支持。彼得·迪莫夫在mini-review获取和设置基本算术类型(或<cstdint>
等价物)从/到无符号字符数组的偏移量是常见的需要。请参见促进。Endian迷你预览发布.
超出范围检测。彼得·迪莫夫在对超出范围的缓冲区值抛出异常的小审查令人满意。请参阅的结尾这个帖子以及随后的答复。
收到Adder、Benaka Moorthi、,Christopher Kohlhoff、Cliff Green、Daniel James、Dave Handley、Gennaro Proto、Giovanni Piero德雷塔、戈登·伍德赫尔、晕眩、哈特穆特·凯泽、霍华德·希南特、杰森·牛顿、杰夫·弗林、杰里米·梅丁·谢泼德、约翰·费罗、约翰马多克(Maddock)、金·巴雷特(Kim Barrett)、马歇·雷(Marsh Ray)、马丁·邦纳(Martin Bonner)、马蒂亚斯·高纳德(Mathias Gaunard)、马提亚斯(Matias)卡佩莱托、尼尔·梅休、内文·利伯,奥拉夫·范德斯佩克、保罗·布里斯托、彼得·迪莫夫、皮埃尔·塔尔博特、菲尔·恩德科特,Philip Bennefall、Pyry Jahkola、,雷内·里维拉、罗伯特·斯图尔特、罗杰·利、罗兰·施瓦兹、斯科特·麦克默里、塞巴斯蒂安·雷德、蒂姆布莱希曼、蒂姆·摩尔、蒂莫菲、托马斯·普维尔、文森特·博特、尤瓦尔·罗宁和维塔利·布多夫斯克。如果有人错过了,请致歉。
上次修订时间:2016年4月5日
©Beman Dawes版权所有,2011年、2013年
根据Boost软件许可证1.0版进行分发。请参见www.boost.org/许可证_1_0.txt