C++ FPU控制功能是否与x64_64处理器相关?
我问这个问题是因为我试图在Visual Studio 2017(cl.exe)和gcc 5.4.0之间实现位(哈希)相等。有问题的函数使用sin()和cos()。所有变量都是双变量,FMAD也是相关的 我一直在SO和网络上广泛阅读有关浮点决定论、可复制性和锁存MP游戏设计的内容。我知道单编译器、单构建决定论并不难,但我正在尝试双编译器、单构建决定论 这里不关心效率。我只是想让结果吻合 我这样问是因为我希望缩小我对测试/尝试内容的顾虑 这些与x86_64处理器和构建相关吗C++ FPU控制功能是否与x64_64处理器相关?,c++,c,C++,C,我问这个问题是因为我试图在Visual Studio 2017(cl.exe)和gcc 5.4.0之间实现位(哈希)相等。有问题的函数使用sin()和cos()。所有变量都是双变量,FMAD也是相关的 我一直在SO和网络上广泛阅读有关浮点决定论、可复制性和锁存MP游戏设计的内容。我知道单编译器、单构建决定论并不难,但我正在尝试双编译器、单构建决定论 这里不关心效率。我只是想让结果吻合 我这样问是因为我希望缩小我对测试/尝试内容的顾虑 这些与x86_64处理器和构建相关吗 控制x87 fpu的函数
- 仅使用带精确舍入的浮点运算(融合乘法累加+泰勒级数)实现您自己的正弦/余弦
- 使用具有强烈舍入考虑的第三方库
自定义实现 请注意,如果您决定自己实现它,则需要选择舍入模式并通知编译器这对您很重要 在C++中,这样做是:
#include <cfenv>
#pragma STDC FENV_ACCESS ON
#pragma STDC FP_CONTRACT OFF
int main(int, char**) {
...
if(!std::fesetround(FE_TONEAREST))
throw std::runtime_error("fesetround failed!");
...
}
#包括
#布拉格STDC FENV_通道
#布拉格STDC FP_合同关闭
int main(int,char**){
...
如果(!std::fesetround(feu TONEAREST))
抛出std::runtime_错误(“fesetround失败!”);
...
}
gcc和MSVC使用不同的标准库,因此trig函数的实现可能不同。除此之外,SIMD的不同硬件实现可以给出不同的答案。在两个平台上使用相同的第三方数学库(例如MKL)可能会更幸运。根据我的经验,如果您能够在两种平台上始终获得精确的按位结果,您将是幸运的。也许你已经读过了——一个mcve演示这个问题会很有用。我认为如果你想让sin/cos相同,那么你需要使用相同的实现(即找到/创建这些函数的实现,并将它们包含到你的项目中)。这是因为SSE没有sin/cos,所以它们是通过某种算法实现的。不同的库将为您提供不同的保证(唯一的例外是,如果它们保证使用相同的舍入得到最精确的结果)。您可能会发现这很有用。例如,crlibm为sin/cos提供正确的舍入结果(我没有使用此库)。此答案最能解决我的问题;这是(最有可能的)不同平台和构建的sin/cos实现。如果没有人在x64上发布关于FPU的答案,我会选择这个。注意,我不会在游戏引擎中使用MPFR。它被设计成尽可能精确(精确的四舍五入),这对于您的目的来说可能太贵了。在您的情况下,我会选择自定义实现,但不要忘记使用std::fesetround和STDC pragma设置舍入模式。