Java中的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标准。 该标准适用于所有平台,但它有溢出和下溢等缺点。

有些平台已经优化了存储浮点数的方法,自Java 1.2起,JVM尝试使用这些优化的function。 问题是,现在各个平台的缺点可能不同甚至完全消失。

因此,任何依赖这些缺点的代码可能无法在某些平台上运行, strictfp关键字是作为一种变通方法引入的。 使用此关键字时,Java将使用IEEE标准,从而在所有平台上实现更高的兼容性。

但是,由于不再使用平台优化,因此使用strictfp浮点计算会更慢。

关于性能,你不应该使用/不使用strictfp关键字来混合代码,因为它可能导致20%-30%的性能损失(在精确的傅里叶变换上在JDK 1.7上测试)。

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

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