14

我正在编写一个视频游戏Humm and Strumm,它的游戏引擎中需要一个网络组件。我可以轻松处理字节顺序的差异,但在尝试处理可能的float内存格式时遇到了困难。我知道现代计算机都有标准的整数格式,但我听说它们可能并不都使用 IEEE 浮点整数标准。这是真的?

虽然我当然可以将它作为字符串输出到每个数据包中,但无论平台如何,我仍然必须转换为每个客户端的“众所周知的格式”。标准printf()atod()将是不充分的。

请注意,因为这个游戏是一个免费/开源软件程序,可以在 GNU/Linux、*BSD 和 Microsoft Windows 上运行,所以我不能使用任何专有解决方案,也不能使用任何单一平台解决方案。

干杯,
帕特里克

4

3 回答 3

7

如果您正确抽象您的网络接口,您可以拥有序列化和反序列化浮点数据类型的函数/对象。在我能想到的每个系统上,这些都是 IEEE 标准,因此您只需让它们原封不动地传递数据(编译器甚至可能会对其进行优化,因此您不会失去任何性能)。如果您确实遇到了一些具有不同格式的系统,您可以有条件地在这些函数中编译一些代码,以进行位黑客攻击,将 IEEE 标准转换为本机格式。您只需要在一处进行更改。但是,除非您进入控制台/手持设备/等,否则您可能永远不需要这样做。

于 2010-04-27T19:44:58.067 回答
7

我认为可以安全地假设每个平台都有一个你可以依赖的 IEE-754 规范的实现,但是,即使它们都实现了相同的规范,也不能保证每个平台都有完全相同的实现,有设置相同的 FP 控制标志,执行相同的优化,或实现相同的非标准扩展。这使得浮点确定性非常难以控制,并且在这种情况下使用起来有些不可靠(您将通过网络传达 FP 值)。

有关这方面的更多信息;阅读http://gafferongames.com/networking-for-game-programmers/floating-point-determinism/

另一个需要解决的问题是处理没有浮点单元的客户端;大多数情况下,这些将是低端 CPU、控制台或嵌入式设备。如果您想定位他们,请务必考虑到这一点。可以进行 FP 仿真,但在这些设备上往往非常慢,因此您必须掌握定点计算的窍门。但请注意,编写复杂的类以将浮点和定点计算抽象到相同的代码听起来像是一个计划;但在大多数设备上不是。在处理定点值时,它不允许您挤出最大的精度和性能。

另一个问题是处理浮点值的字节顺序,因为您不能只交换字节并再次将 'm 堆栈在浮点寄存器中(字节可能有不同的含义,请参阅http://www.dmh2000.com/cpp/ dswap.shtml)。

我的建议是将浮点数转换为定点中间值,如果需要进行字节序校正并传输它。另外,不要假设在不同机器上进行两次浮点计算会产生相同的结果;他们没有。但是,IEEE-754 以外的浮点实现很少见。例如,GPU 倾向于使用定点,但现在更有可能拥有 IEEE-754 的子集,因为它们不想处理被零除的异常,但它们将具有适合的半浮点数扩展16 位。

还要意识到已经有一些库已经为您解决了这个问题(在游戏环境中发送低级数据格式)。RakNet 就是一个这样的库,特别是它的 BitStream 类旨在将这些类型的数据可靠地发送到不同的平台,同时将开销保持在最低限度;例如,RakNet 在不浪费任何带宽发送字符串或向量方面遇到了一些麻烦。

于 2010-04-27T20:07:42.747 回答
2

一些嵌入式处理器根本不包含任何浮点硬件。对于台式计算机,我认为没有任何理由过分担心,除了那些只会让专家真正烦恼的细节(sqrt在 Alpha 上被错误地四舍五入,这种事情。让他们烦恼的差异在于操作的实施,而不是无论如何,格式)。

平台之间的一种变化与denormals的处理有关。不久前我问了一个关于这些的问题。即使这样也没有我想象的那么糟糕。

于 2010-04-27T19:43:01.547 回答