Pat*_*ski 14 c++ memory types network-programming ieee-754
我正在写一个视频游戏,Humm和Strumm,它需要在游戏引擎中使用网络组件.我可以很容易地处理字节序的差异,但是我试图处理可能的float内存格式时遇到了障碍.我知道现代计算机都有标准的整数格式,但我听说他们可能都不会将IEEE标准用于浮点整数.这是真的?
虽然我当然可以将它作为字符串输出到每个数据包中,但我仍然需要转换为每个客户端的"众所周知的格式",无论平台如何.标准printf()并且atod()不够.
请注意,因为这个游戏是一个可以在GNU/Linux,*BSD和Microsoft Windows上运行的免费/开源软件程序,所以我不能使用任何专有解决方案,也不能使用任何单平台解决方案.
干杯,
帕特里克
如果正确地抽象网络接口,则可以使用序列化和反序列化float数据类型的函数/对象.在我能想到的每个系统上,这些都是IEEE标准,所以你只需让它们通过不变的数据传递(编译器甚至可以优化它,所以你不会失去任何性能).如果您确实遇到了一些具有不同格式的系统,您可以在这些函数中的某些代码中有条件地编译以进行一些黑客攻击,以便从IEEE标准转换为本机格式.您只需要在一个地方更改它.但是,您可能永远不需要这样做,除非您进入控制台/掌上电脑/等.
我认为可以安全地假设每个平台都有可以依赖的IEE-754规范的实现,但是,即使它们都实现相同的规范,也不能保证每个平台具有完全相同的实现,具有设置相同的FP控制标志,执行相同的优化,或实现相同的非标准扩展.这使得浮点确定性非常难以控制,并且在某种程度上(通过网络传递FP值的地方)使用它有点不可靠.
有关这方面的更多信息; 阅读http://gafferongames.com/networking-for-game-programmers/floating-point-determinism/
要解决的另一个问题是处理没有浮点单元的客户端; 大多数情况下,这些将是低端CPU,控制台或嵌入式设备.如果要定位它们,请务必考虑到这一点.可以完成FP仿真,但在这些设备上往往非常慢,因此您必须掌握固定点计算.但是请注意,编写精心设计的类来抽象浮点和定点计算到相同的代码听起来像一个计划; 但在大多数设备上都没有.在处理定点值时,它不允许您挤出最大精度和性能.
另一个问题是处理浮点值的字节序,因为你不能只是交换字节并再次在浮点寄存器中堆栈'(字节可能有不同的含义,参见http://www.dmh2000.com/cpp/关于dswap.shtml).
我的建议是将浮点数转换为定点中间值,如果需要进行字节序修正并传输.此外,不要假设不同机器上的两个浮点计算将产生相同的结果; 他们没有.但是,IEEE-754以外的浮点实现很少见.例如GPU往往使用固定点,但现在更有可能拥有IEEE-754的子集,因为他们不想处理除零的异常,但是它们将具有适合的半浮点数的扩展16位.
还要意识到有些库已经解决了这个问题(在游戏环境中发送低级数据格式).一个这样的库是RakNet,特别是它的BitStream类旨在将这些类型的数据可靠地发送到不同的平台,同时将开销降至最低; 例如,RakNet在发送字符串或向量时不会浪费任何带宽会遇到很多麻烦.