Java中的strictfp

Java中的strictfp,java,floating-point,strictfp,Java,Floating Point,Strictfp,我正在用java实现一些神经网络库,有密集的double(不是double)矩阵运算,矩阵很大,当然需要性能 因此,我来阅读有关strictfp关键字的文章,我真的不明白它到底做了什么,我想简单解释一下我是否应该使用它,以及为什么strictfp表示浮点计算应该使用确切的IEEE754标准。如果没有strictfp,VM可以自由使用中间浮点值和双精度值的其他(但依赖于平台)表示,以提高精度 如果需要在多个平台上获得完全相同的结果,请使用strictfp。如果您希望获得当前平台所能提供的最佳精度,

我正在用java实现一些神经网络库,有密集的
double
(不是
double
)矩阵运算,矩阵很大,当然需要性能


因此,我来阅读有关strictfp关键字的文章,我真的不明白它到底做了什么,我想简单解释一下我是否应该使用它,以及为什么strictfp表示浮点计算应该使用确切的IEEE754标准。如果没有strictfp,VM可以自由使用中间浮点值和双精度值的其他(但依赖于平台)表示,以提高精度

如果需要在多个平台上获得完全相同的结果,请使用strictfp。如果您希望获得当前平台所能提供的最佳精度,请避免使用它

例如,在以下简单添加中:

  2.0 + 1.1 + 3.0
您希望中间结果(例如2.0+1.1)表示为IEEE754标准双精度,还是以平台允许的最佳精度表示。strictfp确保第一个选项,而不使用strictfp允许VM使用第二个选项


不使用strictfp不会影响性能,并且在本机浮点类型不映射到IEEE754的平台上可能会提高性能,因为VM不需要在本机和IEEE754格式之间来回转换。答案取决于平台,您需要进行测量。

有一个关于存储浮点数的IEEE标准。该标准在所有平台上都能很好地工作,但它有一些缺点,例如溢出和下溢

一些平台已经优化了存储浮点数的方法,自Java1.2以来,JVM尝试使用这些优化的能力。问题是,现在不同平台的缺点可能不同,甚至完全消失

因此,任何依赖于这些缺点的代码都可能无法在某些平台上工作,因此引入了
strictfp
关键字作为解决方法。当您使用这个关键字时,Java将使用IEEE标准,从而在所有平台上实现更大的兼容性


但是,由于不再使用平台优化,使用strictfp进行浮点计算的速度较慢,考虑到性能,您不应该将代码与strictfp关键字混用/不使用strictfp关键字混用,因为这会导致20%-30%的性能损失(在JDK 1.7上测试精确傅立叶变换)


关于准确度,两者都是相同的(超过1e-14绝对或相对误差):它只允许使用更大的指数来避免下溢或溢出

如果您希望其他研究人员在给定相同训练数据和相同随机种子的情况下训练完全相同的神经网络,而不管他们的CPU如何,请使用
stricfp
。科学结果的再现性(或精确单位测试)是strictfp的主要用途。对于日常使用,它会损害性能和数值稳定性。

strictfp和not re性能之间的差异可能可以忽略不计(如果有的话),并且在不同的平台上可能会走向相反的方向。但是,如果您非常关心它,请从两个方面对其进行测试,并选择“更快”的一个。值得一提的是,如果没有strictfp,溢出或下溢等情况可能会产生真正不同的结果。如果您想了解有关此修饰符的更多信息,请参阅oracle的详细定义:可能重复