8

我正在为 iOS 开发一个带有 Box2D 物理的多人游戏。多人游戏像往常一样使用锁步方法。游戏定时更新物理世界。具有相同 CPU 的 iOS 设备之间不存在不同步。

但是,在使用 Apple A6 芯片的新 iOS 设备进行测试时,发生了不同步。查看我的日志文件给我的印象是异步发生的速度非常快,这可能是因为一些浮点操作我还没有找到。

我可以保证只有Box2D是游戏设计中唯一需要同步的模块,根据我的日志,所有的多人游戏命令和输入都没有不同步。

我尝试将所有超验函数:sinf、cosf、pow、sqrtf、atan2f 更改为双版本,但没有任何运气。

有什么方法可以强制 Apple A6 将浮点数与 Apple A5 一样处理,就像某些编译器选项一样?

我将非常感谢任何答案。

4

3 回答 3

5

许多数学库函数在 A5 和 A6 上使用不同的算法。如果它们的差异超过一两个 ulp,您可能发现了一个错误;请报告。否则,变化可能在高质量数学库的预期容差范围内。要了解为什么会这样,最好的参考是 Ian Ollmann 几年前发给 mac-games-dev 邮件列表的电子邮件,“数学库不是安全工具”,它在 Mac OS X 的上下文中解决了这个确切的问题。(tl;dr 版本是一些游戏开发人员想要的跨架构提供位相同结果的目标从根本上与提供高精度答案相冲突,因为在所有架构上尽可能高效,这是所有开发人员 [和用户,因为它有利于响应能力和电池寿命] 想要的;必须给予一些东西,对于通用系统库,后者必须优先考虑)。Apple 开发者论坛将是另一个寻找信息的好地方。

于 2012-12-16T23:48:30.483 回答
3

实际上又是阮长中。

到目前为止,非常感谢大家的回答。我非常感谢您的回答,这为我提供了继续调试的途径!目前,我以某种方式找到了不同步的原因,但还没有具体的解决方案。我希望向您提供我得到的信息,希望我能得到更多的见解。

1. 发现:

我有这个使用cos的功能。我这样打印日志:

void rotateZ(浮动角度)

{

 if( angle )

 {

      const float sinTheta = sin( angle );

      const float cosTheta = cos( angle );



      // I logged here

      myLog( "Vector3D::SelfRotateZ(%x) %x, %x", *(unsigned int*)&angle, *(unsigned int*)&cosTheta, *(unsigned int*)&sinTheta );



      ....
 }

}

异步是这样发生的:

在 iPad4 上:Vector3D::SelfRotateZ(404800d2) bf7ff708, 3c8782bc 在 iPhone4 上:Vector3D::SelfRotateZ(404800d2) bf7ff709, 3c8782bc

2.重新测试:

故事并不止于此,因为:

  1. 我在游戏开始时尝试了这些代码行:

{ 无符号整数 zz = 0x404800d2;

float yy = 0;

memcpy( &yy, &zz, 4 );

const float temp1 = cos( yy );


printf( "%x\n", *(unsigned int*)&temp1;

}

  1. 我在同一个 iPhone4 上运行了上面的代码,你猜怎么着?我得到了这个:bf7ff708

  2. 我将该代码放入游戏的更新循环中,我得到的结果在每个循环中仍然是 bf7ff708。

  3. 更?值 0x404800d2 是游戏的初始化值,所以每次游戏开始时,上面的两条不同步行总是在那里。

3:提问:

所以,我决定忘记上面发生的事情,暂时用我在 dreamcode.net 上找到的简单 Taylor 实现替换 sin、cos 函数。不再发生不同步。

似乎 cos 函数在同一个 iPhone 4(OS 版本 5)上甚至都不是确定性的。

我的问题是:我们有没有解释为什么 cos 函数在同一部手机上为相同的输入返回不同的结果?这里我有输入 0x404800d2,以及两个不同的输出:bf7ff708 和 bf7ff709。但是,我无法通过简单的编码来重现结果 bf7ff709。

我想我需要操作系统的数学函数(浮点版本)的源代码才能清楚地理解这一点。我发现的上述问题是否足以作为错误报告?

于 2012-12-18T10:02:55.823 回答
1

实际上又是阮长中。:)

非常感谢您迄今为止的帮助。

我只想报告,在我重写了所有超越函数(如 cos、sin、sqrt、pow、atan2、atan、asin、acos 等(尽可能多))后,异步已修复。

于 2012-12-19T15:38:21.667 回答