web-dev-qa-db-ja.com

javaで「strictfp」キーワードを使用する必要があるのはいつですか?

私はこれが何をするのか調べましたが、実際にJavaでstrictfpキーワードを使用する場合の例はありますか?誰かが実際にこれを使用しましたか?

すべての浮動小数点演算にそれを置くだけの副作用はありますか?

248
GBa

Strictfpは、すべてのプラットフォームで浮動小数点計算からまったく同じ結果を確実に取得します。 strictfpを使用しない場合、JVM実装は、可能な場合は自由に追加の精度を使用できます。

JLSから

FP-strict式内では、すべての中間値はfloat値セットまたはdouble値セットの要素である必要があります。つまり、すべてのFP-strict式の結果は、singleおよびdouble形式を使用して表されるオペランドでIEEE 754算術演算によって予測されたものでなければなりません。 FPに厳密ではない式内では、拡張された指数範囲を使用して中間結果を表すための実装に多少の余裕が与えられます。大まかに言うと、フロート値セットまたはダブル値セットを排他的に使用するとオーバーフローまたはアンダーフローが発生する可能性がある状況では、計算によって「正しい答え」が生成される可能性があります。

つまり、Write-Once-Run-Anywhereが実際にWrite-Once-Getを意味することを確認することです-等しく-間違った結果-どこでも

Strictfpを使用すると、結果は移植可能になりますが、それなしでは結果が正確になる可能性が高くなります。

262
Dan Dyer

ウィキペディアには、実際にこのトピックに関する良い記事があります こちら 、Java仕様へのリンクがあります。

行間を読むと、strictfpを指定しない場合、JVMおよびJITコンパイラーは浮動小数点計算を必要に応じて計算するライセンスを持っているという意味になります。速度を向上させるために、ほとんどの場合、計算をプロセッサに委任します。 strictfpがオンの場合、計算はIEEE 754算術標準に準拠する必要があります。これは、実際には、おそらくJVMが計算を行うことを意味します。

では、なぜstrictfpを使用するのでしょうか?私が見ることができる1つのシナリオは、基礎となるハードウェアまたはCPUが何であっても、すべての浮動小数点計算が決定論的である必要がある分散アプリケーション(またはマルチプレイヤーゲーム)です。トレードオフは何ですか?最も可能性の高い実行時間。

63
MattK

すべては物語から始まりました

JavaがJames Gosling、Herbertおよび彼のチームの残りによって開発されていたとき。彼らはplatform independencyと呼ばれるこのクレイジーなことを念頭に置いていました。彼らはOak(Java)を非常に良くして、異なるオペレーティングシステムを実行していても、異なる命令セットを持つ任意のマシンでまったく同じに実行することを望んでいました。しかし、プログラミング言語では浮動小数点および倍精度としても知られている小数点数に問題がありました。一部のマシンは効率を目標として構築され、残りは精度を目標としていました。したがって、後の(より正確な)マシンの浮動小数点サイズは80ビットで、前の(より効率的/高速な)マシンは64ビットの倍精度でした。しかし、これはプラットフォームに依存しない言語を構築するという中核的なアイデアに反していました。また、コードが何らかのマシン(64ビットサイズの2倍)でビルドされ、別の種類のマシン(80ビットサイズの2倍)で実行される場合、精度/データの損失につながる可能性があります。

アップサイジングは許容できますが、ダウンサイジングは許容できません。そのため、strictfpの概念、つまりstrict floating pointに出会いました。このキーワードをクラス/関数で使用すると、浮動小数点と倍精度はどのマシンでも一貫したサイズになります。つまり、それぞれ32/64ビットです。

22
AbhimanyuAryan

いくつかの参照があります:

  • strictfpを使用 (JDC Tech Tip)
  • jGuru: strictfp修飾子は何のためですか?いつ使用することを検討しますか?

    基本的に、すべてを要約すると、コード内の浮動小数点式の結果が高速または予測可能かどうかを気にするかどうかです。たとえば、複数のプラットフォーム間で一貫性を保つために浮動小数点値を使用するコードで考えられる答えが必要な場合は、strictfpを使用します。

  • strictfp-Java用語集

    浮動小数点ハードウェアは、Java仕様が要求するよりも高い精度で、より広い範囲の値で計算します。一部のプラットフォームが他のプラットフォームよりも精度が高い場合、混乱するでしょう。メソッドまたはクラスでstrictfp修飾子を使用すると、コンパイラは、すべてのプラットフォームで同一の結果を得るためにJava仕様に厳密に従うコードを生成します。 strictfpがなければ、わずかにゆるいですが、Pentiumでガードビットを使用して80ビットの精度を与えるほどゆるくないです。

  • そして最後に、実際のJava言語仕様、 §15.4FP-strict Expressions

    FP-strict式内では、すべての中間値はfloat値セットまたはdouble値セットの要素である必要があります。つまり、すべてのFP-strict式の結果は、singleおよびdouble形式を使用して表されるオペランドでIEEE 754算術演算によって予測されたものでなければなりません。 FPに厳密ではない式内では、拡張された指数範囲を使用して中間結果を表すための実装に多少の余裕が与えられます。大まかに言うと、フロート値セットまたはダブル値セットを排他的に使用するとオーバーフローまたはアンダーフローが発生する可能性がある状況では、計算によって「正しい答え」が生成される可能性があります。

しかし、私は個人的にそれを使用したことがありません。

21
Michael Myers

他の回答で述べたように、中間浮動小数点の結果はIEEE仕様に準拠します。特に、x86プロセッサは、IEEE仕様とは異なる精度で中間結果を保存できます。 JITが特定の計算を最適化すると、状況はさらに複雑になります。命令の順序は毎回異なる可能性があり、結果として丸めがわずかに異なります。

Strictfpによって発生するオーバーヘッドは、プロセッサとJITに大きく依存する可能性があります。 SSE2 に関するこのウィキペディアの記事には、この問題についての洞察があるようです。したがって、JITがSSE命令を生成して計算を実行できる場合、strictfpにはオーバーヘッドが発生しないようです。

現在のプロジェクトでは、strictfpを使用する場所がいくつかあります。潜在的な宇宙線をピクセル値から削除する必要があるポイントがあります。外部の研究者の前に同じピクセル値と宇宙線がある場合、ソフトウェアと同じ結果値を取得する必要があります。

12
Sean McCauliff
  • strictfpは、IEEE 754に従って浮動小数点計算を制限する修飾子です。

  • これは、「public strictfp class StrictFpModifierExample {}」などのクラス全体または「public strictfp void example()」メソッドで使用できます。クラスで使用すると、すべてのメソッドがIEEE 754に準拠し、メソッドで使用すると特定のメソッドが使用されますIEEE 754に従ってください。

  • なぜ使用されるのですか?:::プラットフォームごとに異なる浮動小数点ハードウェアがあるため、Java仕様が必要とするよりも高い精度と値の範囲で計算し、異なるプレートフォームで異なる出力を生成する場合があります。異なるプレート形状に関係なく出力

  • また、strictfpは、拡張精度浮動小数点演算の速度と精度を確実に活用します。

  • このキーワードには、浮動小数点計算を行うときに使用できるデメリットはありません

  • 私の最後のポイントは、IEEE754とは何ですか?IEEE 754は、浮動小数点計算と、シングル(32ビット、Java floatで使用)またはダブル(64ビット、Java doubles)precisionで使用されます。また、中間計算および拡張精度形式の基準も定義します。

8
Rahul Saxena

strictfpはキーワードであり、クラスまたはメソッドの非アクセス修飾子として使用できます(ただし、変数は使用できません)。クラスをstrictfpとしてマークすると、クラス内のメソッドコードはすべて、浮動小数点に関するIEEE 754標準規則に準拠します。

この修飾子がないと、メソッドで使用される浮動小数点はプラットフォームに依存した方法で動作する可能性があります。これにより、JVMが実行されている基盤となるプラットフォームに関係なく、浮動小数点の動作を予測できます。欠点は、基礎となるプラットフォームがより高い精度をサポートできる場合、strictfpメソッドはそれを利用できないことです。

クラスをstrictfpとして宣言しない場合でも、メソッドをstrictfpとして宣言することにより、メソッドごとにstrictfp動作を取得できます。

〜SC™Sun®CertifiedProgrammer for Java™6-キャシーシエラ&バートベイツ〜

2