私はJavaでいくつかのニューラルネットワークライブラリを実装していますが、集中的なdouble(ではないDouble)行列演算があり、行列は大きく、もちろんパフォーマンスが必要です。
それで、strictfpキーワードについて読むようになりました。正直なところ、それが何をするのか正確には理解できませんでした。それを使用すべきかどうか、そしてその理由についての簡単な説明を探していました。
私はJavaでいくつかのニューラルネットワークライブラリを実装していますが、集中的なdouble(ではないDouble)行列演算があり、行列は大きく、もちろんパフォーマンスが必要です。
それで、strictfpキーワードについて読むようになりました。正直なところ、それが何をするのか正確には理解できませんでした。それを使用すべきかどうか、そしてその理由についての簡単な説明を探していました。
strictfpは、浮動小数点の計算で正確なIEEE754標準を使用する必要があることを示します。strictfpがない場合、VMは、精度を上げるために、中間のfloat値とdouble値の他の(ただしプラットフォームに依存する)表現を自由に使用できます。
複数のプラットフォームでまったく同じ結果が必要な場合は、strictfpを使用してください。現在のプラットフォームで得られる最高の精度が必要な場合は、これを避けてください。
たとえば、次の簡単な追加で:
2.0 + 1.1 + 3.0
中間結果(2.0 + 1.1など)をIEEE754標準のdoubleとして表現するか、プラットフォームで可能な限り最高の精度で表現するか。strictfpは、最初の方法を保証します。strictfpを使用しない場合、VMは2番目の方法を使用できます。
strictfpを使用しなくてもパフォーマンスが低下することはなく、ネイティブの浮動小数点型がIEEE754にマップされていないプラットフォームでは、VMがネイティブ形式とIEEE754形式の間で相互に変換する必要がないため、パフォーマンスが向上する可能性があります。答えはプラットフォームに依存するため、測定する必要があります。
浮動小数点数の格納に関するIEEE標準があります。この標準はすべてのプラットフォームでうまく機能しますが、たとえばオーバーフローやアンダーフローなどのいくつかの欠点があります。
一部のプラットフォームでは、浮動小数点数を格納する方法が最適化されています。Java1.2以降、JVMはこれらの最適化された機能を使用しようとします。問題は、現在、欠点がプラットフォームごとに異なる可能性があるか、完全になくなる可能性があることです。
したがって、これらの欠点に依存していたコードは、一部のプラットフォームでは機能しない可能性があります。このstrictfpキーワードは回避策として導入されました。このキーワードを使用すると、JavaはIEEE標準を使用するため、すべてのプラットフォームでの互換性が向上します。
ただし、プラットフォームの最適化は使用されなくなったため、浮動小数点の計算は。で遅くなりstrictfpます。
パフォーマンスに関しては、strictfpキーワードを含む/含まないコードを混在させないでください。20%〜30%のパフォーマンスペナルティが発生する可能性があります(正確なフーリエ変換でJDK 1.7でテスト済み)。
精度に関しては、両方とも同じです(1e-14を超える絶対誤差または相対誤差):アンダーフローまたはオーバーフローを回避するために、より大きな指数の使用のみが可能です。
CPUに関係なく、同じトレーニングデータと同じランダムシードを指定して、他の研究者にまったく同じニューラルネットをトレーニングさせたい場合は、を使用しますstrictfp。科学的結果(またはビット精度の単体テスト)の再現性は、strictfpの主な用途です。日常の使用では、パフォーマンスと数値安定性に悪影響を及ぼします。