我在 java 中实现了一些神经网络库,并且有密集的double
(不是Double
)矩阵运算,矩阵很大,当然需要性能。
因此,我开始阅读有关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 尝试使用这些优化的能力。问题是,现在这些缺点可能因平台而异,甚至完全消失。
因此,依赖于这些缺点的任何代码可能无法在某些平台上运行,strictfp
因此引入了关键字作为解决方法。当您使用此关键字时,Java 将使用 IEEE 标准,从而在所有平台上实现更高的兼容性。
但是,由于不再使用平台优化,浮点计算在strictfp
.
关于性能,您不应将代码与 / 不包含 strictfp 关键字混合,因为它会导致 20% - 30% 的性能损失(在 JDK 1.7 上进行精确傅立叶变换测试)。
关于精度两者是相同的(超过 1e-14 绝对或相对误差):它只允许使用更大的指数来避免下溢或上溢
如果您希望其他研究人员在给定相同训练数据和相同随机种子的情况下训练完全相同的神经网络,而不管他们的 CPU 是多少,请使用strictfp
. 科学结果的可重复性(或位精确单元测试)是 strictfp 的主要用途。对于日常使用,它会损害性能和数值稳定性。