c++ - 使用正确的编译器标志在每个平台上进行相同的模拟

标签 c++ gcc cross-platform game-engine compiler-optimization

我开发游戏 Remnants of Naezith 大约 2.5 年,这款游戏的支柱是排行榜,它有重播。游戏是完全确定性的,因此相同的输入每次都会导致相同的模拟。 游戏完全用 C++ 和 SFML 从头开始​​编写

几个月前,我将我的 gcc 编译器从 64 位更改为 32 位或相反,我记错了,但问题是,旧的回放在新编译器中不起作用。当我搜索它时, float 学在两者之间是不同的。

我通过放置 -msse2 -mfpmath=sse 修复了它。然后一切正常。

今天我在 Debug模式下编译并运行了游戏,这是我第一次看到一些回放再次不同步。当我搜索它时,它是由我在发布版本中使用的 -Ofast 标志引起的。因为 -Ofast 标志中有 -ffast-math。这会导致计算不同,因此模拟也会不同。

目前使用此 -Ofast 标志不会导致任何问题,因为每个人都在具有该标志的构建中玩游戏。

将来我想将我的游戏移植到 Mac、Linux、PS4、Xbox 或其他平台。我的排行榜在我自己的服务器上,所以我想使用所有平台共享的相同排行榜。这就是为什么我需要游戏在每个平台上都完全相同。

我怀疑如果我保留这个-Ofast,每个人都会玩它,当我需要将我的游戏移植到另一个平台时,我可能需要更改我的编译器,而那个编译器可能不会具有相同的标志,或者数学在该编译器中的工作方式可能不同。

我应该避免哪些标志以及我应该选择哪些标志以确保它将模拟相同的回放,在每个平台上都相同

编辑: 避免 -Ofast 以摆脱 -ffast-math 听起来很明显,但我还应该使用什么,它会好吗之后呢?

最佳答案

这将很难实现。

当然,如果您的目标是 32 位和 64 位 x86/amd64 架构,您希望对两者都使用 SSE,否则在 32 位 x86 上您最终可能会使用 x87,这肯定会导致差异。

即使您可以消除自己编译代码中的任何差异,您也可能会遇到标准库中的差异。例如,我发现 FreeBSD/Solaris 和 Linux 之间 std::pow() 的实现存在差异。

我想使用定点表示是不可能的?

关于c++ - 使用正确的编译器标志在每个平台上进行相同的模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43238368/

相关文章:

c++ - 关于 `std::vector::push_back`声明的选择

c++ - 复制初始化和显式构造函数 - 编译器差异

docker - 根据主机操作系统在Docker Compose中更改镜像

c++ - 在 Linux 上编译简单信号代码时从 void* 到 void (*) int 的无效转换

android - 如何从 JNI 启动一个新线程

c++ - Cmake:使用导入的对象

gcc 中的 C 副作用(前缀/后缀运算符和优先级)

c - 外部链接内联函数定义是否需要 `extern`?

ios - 将 Microsoft Team Foundation Server 集成到 iOS 应用程序中的推荐方法是什么

ruby - 启用将文件拖放到 Ruby 脚本上