- 主题:[转载]说到浮点数,有个 BUG 很有意思
在花了大约一天时间,重新使用当年的调试和回放工具之后,一位同事弄明白了哪里出了问题。
如果仔细观看游戏,你会发现这扇门有一瞬间,其实自动解锁并打开了,但是房间里还有第二个守卫站在门后。这个守卫站得离门非常近,门打开的一瞬间会轻轻碰到守卫的脚趾,然后又弹回,重新关上,并自动上锁。由于游戏没有考虑怎么处理这种情况并重新打开门,所以游戏就卡住,你无法前进了。
一旦弄明白怎么回事,解决方法就很简单。我们把守卫往后移大约一毫米,门就很顺利自动打开了。
现在我们可以发布游戏了。但是,问题还是没有彻底解决。为什么这个游戏当初没有出现这个 Bug,原版里守卫的脚趾也挡着门啊?为什么十年后重新编译,Bug 就出现呢?或者说,Bug 其实一直都在,为什么十年前这扇门没有关上呢?
于是,一场旷日持久的漏洞搜寻就此展开。
我们终于发现了答案,就是老生常谈的浮点运算。
《半条命2》于2004年发布,当时编译用的是较旧的8087或 x87 数学指令集。这些指令集的浮点数精度五花八门,有些是32位,有些是64位,有些是80位,不同的代码段使用了不同的精度。
十年后的2013年,SSE 指令集已经成为所有 x86 CPU 的标准配置,编译器默认使用 SSE,它有明确的精度,根据代码需求使用32位或64位,是可以预测的。
真相就是,十年前编译用了32位精度,现在用了64位,小数点的差异造成了几毫米的误差,让守卫的脚趾碰到了门。
好了,现在玩家终于可以走进大门,继续玩下去了。
--
修改:hgoldfish FROM 27.152.53.*
FROM 112.51.42.*
这明显是程序员的锅,怎么能甩给cpu呢
x87支持32b,8x8b,80b的浮点精度
SSE其实只能支持32b
SSE2增加了8x8b
最近又增加了16b
cpu支持多种浮点精度程序员就不会编程了吗?
明显是这个程序员没有做合适的误差分析
【 在 hgoldfish 的大作中提到: 】
: 在花了大约一天时间,重新使用当年的调试和回放工具之后,一位同事弄明白了哪里出了问题。
: 如果仔细观看游戏,你会发现这扇门有一瞬间,其实自动解锁并打开了,但是房间里还有第二个守卫站在门后。这个守卫站得离门非常近,门打开的一瞬间会轻轻碰到守卫的脚趾,然后又弹回,重新关上,并自动上锁。由于游戏没有考虑怎么处理这种情况并重新打开门,所以游戏就卡住,
: 阄薹ㄇ敖恕
: ...................
--
FROM 71.198.4.*
大赞
【 在 hgoldfish 的大作中提到: 】
: 在花了大约一天时间,重新使用当年的调试和回放工具之后,一位同事弄明白了哪里出了问题。
: 如果仔细观看游戏,你会发现这扇门有一瞬间,其实自动解锁并打开了,但是房间里还有第二个守卫站在门后。这个守卫站得离门非常近,门打开的一瞬间会轻轻碰到守卫的脚趾,然后又弹回,重新关上,并自动上锁。由于游戏没有考虑怎么处理这种情况并重新打开门,所以游戏就卡住,你无法前进了。
: 一旦弄明白怎么回事,解决方法就很简单。我们把守卫往后移大约一毫米,门就很顺利自动打开了。
: ...................
--
FROM 125.34.217.*
明显是cpu的锅,compiler宣称sse能替代x87,它为啥不提示可能出现的运行不一致,至少应该报个warning
【 在 BigCarrot 的大作中提到: 】
: 这明显是程序员的锅,怎么能甩给cpu呢
: x87支持32b,8x8b,80b的浮点精度
: SSE其实只能支持32b
: ...................
--
FROM 125.34.217.*
他们没有用sse时有问题,用了sse就好了
其实用x87时使用指定的精度保存数据,运算时可能采用80b,理论上结果可能会更加精确
sse使用相同的精度来保存和计算
所以他们完全使用sse后结果图形结果就好了,也就是说他们使用了更低精度的计算后
结果就更符合预期了,说明他们还是没有明白问题到底出现在哪里,没有明白哪里的误差
会影响到显示结果,以及如何修理他
当然误差分析属于科学计算领域的必备技能,游戏领域缺少这方面的能力也是能理解的
【 在 tianbing1212 的大作中提到: 】
: 明显是cpu的锅,compiler宣称sse能替代x87,它为啥不提示可能出现的运行不一致,至少应该报个warning
--
FROM 71.198.4.*