【发布时间】:2018-03-31 10:24:39
【问题描述】:
我问这个问题是因为我试图在 Visual Studio 2017 (cl.exe) 和 gcc 5.4.0 之间实现按位(哈希)相等。有问题的函数使用了 sin() 和 cos()。所有变量都是双倍的,FMAD 也是相关的。
我一直在 SO 和网络上广泛阅读有关浮点确定性、再现性和锁存 MP 游戏设计的内容。我知道单编译器、单构建确定性并不难,但我正在尝试 2-编译器、单构建确定性。
这里的效率不是问题。我只希望结果匹配。
我问是因为我希望缩小我对测试/尝试什么的担忧。
这些东西是否与 x86_64 处理器和构建相关?
- 控制 x87 fpu 的函数
- XPFPA_{DECLARE,RESTORE,etc}
- "、_FPU_SINGLE、_FPU_DOUBLE等
- _controlfp_s()、_PC24、_PC53、_PC_64
我问是因为我读过带有 SSE (x86_64) 的平台默认使用 SSE 进行浮点运算,所以 fpu 控制功能应该无关紧要吗?
我发现this 和this 提供的信息最多。 MSDN article 表示 x64 架构不支持设置浮点精度掩码。 this SO post 表示 SSE 具有固定精度。
我的测试表明 /fp:{strict,precise,fast} 没有改变哈希值。优化级别也不是。所以我希望把注意力集中在罪上,因为。
【问题讨论】:
-
gcc 和 MSVC 使用不同的标准库,因此可能会使用不同的触发函数实现。除此之外,SIMD 的不同硬件实现可以给出不同的答案。在两个平台上使用相同的第 3 方数学库(例如 MKL)可能会更幸运。以我的经验,如果你能在两个平台上始终获得精确的按位结果,你会很幸运。也许读过这个 - software.intel.com/en-us/articles/…
-
证明问题的 mcve 会很有用。
-
我认为如果您希望 sin/cos 相同,那么您需要使用相同的实现(即查找/创建这些函数的实现,并将它们包含到您的项目中)。这是因为 SSE 没有 sin/cos,所以这些是通过某种算法实现的。不同的库会为您提供不同的保证(唯一的例外是,如果它们保证使用相同的舍入得到最精确的结果)。
-
您可能会发现this Random ASCII blog entry 很有用。
-
例如,crlibm 为 sin/cos 提供了正确四舍五入的结果(我没用过这个库)