2009-02-05 19 views
221

Ich habe nachgeschaut, was das ist, aber hat jemand tatsächlich ein Beispiel dafür, wann Sie das Schlüsselwort strictfp in Java verwenden würden? Hat jemand tatsächlich einen Nutzen dafür gefunden?Wann sollte ich das Schlüsselwort "strictfp" in Java verwenden?

Wäre es irgendwelche Nebenwirkungen von nur auf alle meine Fließkommaoperationen setzen?

+0

Immer, es sei denn, Sie benötigen die Leistung tatsächlich mehr als Sie Reproduzierbarkeit benötigen. – Antimony

+0

@Antimony - oder die Präzision/Richtigkeit. Beispielsweise verwenden x86/x64 interne 80-Bit-Fließkomma-Register, so dass das Ergebnis für eine lange Berechnung ohne strictfp genauer ist. –

+0

@Robert Tatsächlich garantiert die Spezifikation begrenzte Präzision der Mantisse. Der einzige Unterschied ist, dass es eine größere Exponentenpräzision als normal verwenden kann, die in seltenen Fällen aufgrund von Doppelrundung Unterschiede aufweist. – Antimony

Antwort

226

Strictfp stellt sicher, dass Sie mit Ihren Gleitkommaberechnungen auf jeder Plattform genau die gleichen Ergebnisse erhalten. Wenn Sie strictfp nicht verwenden, kann die JVM-Implementierung bei Bedarf zusätzliche Präzision verwenden.

From the JLS:

Innerhalb einer FP-strengen Ausdruck alle Zwischenwerte müssen Elemente des Schwimmers Wert eingestellt werden, oder die Doppel Wert gesetzt, was bedeutet, dass die Ergebnisse aller FP-strenge Ausdrücke muss die von IEEE 754 vorhergesagten Arithmetik auf Operanden mit einzelnen und Doppelformaten vertreten. Innerhalb eines Ausdrucks, der nicht FP-strikt ist, wird ein gewisser Spielraum für eine Implementierung gewährt, um einen erweiterten Exponentenbereich zu verwenden, um Zwischenergebnisse darzustellen; Der Nettoeffekt, grob gesagt, ist, dass eine Berechnung „ die richtige Antwort“ in Situationen, in denen exklusive Verwendung des Schwimmers Wertesatzes oder Doppel Wertesatzes in Überlauf oder Unterschreitung könnte Ergebnis führen könnte.

Mit anderen Worten geht es darum, sicherzustellen, dass Write-Once-Run-Anywhere- eigentlich bedeutet Write-Once-Get-Gleichermaßen-Wrong-Ergebnis-überall.

Mit strictfp sind Ihre Ergebnisse tragbar, ohne sie sind sie wahrscheinlicher.

+21

Verwenden Sie es für reproduzierbare wissenschaftliche Ergebnisse und bitgenaue Komponententests. –

+60

Write-Once-Get-Gleich-Wrong-Ergebnisse-Überall: D – vach

+0

"Wenn Sie nicht strictfp verwenden, ist die JVM-Implementierung frei, zusätzliche Präzision wo verfügbar zu verwenden" - Sie klingen wie eine schlechte Sache: P –

57

Wikipedia hat eigentlich einen guten Artikel zu diesem Thema here, mit einem Link zu der Java-Spezifikation.

Lesen zwischen den Zeilen, die Implikation ist, dass, wenn Sie strictfp nicht angeben, dann der JVM und JIT-Compiler Lizenz haben, Ihre Gleitkommaberechnungen zu berechnen, wie sie möchten. Im Interesse der Geschwindigkeit werden sie die Berechnung höchstwahrscheinlich an Ihren Prozessor delegieren. Mit strictfp müssen die Berechnungen den IEEE 754-arithmetischen Standards entsprechen, was in der Praxis wahrscheinlich bedeutet, dass die JVM die Berechnung durchführt.

Warum also möchten Sie strictfp verwenden? Ein Szenario, das ich sehen kann, ist in einer verteilten Anwendung (oder Multiplayer-Spiel), wo alle Gleitkommaberechnungen deterministisch sein müssen, egal was die zugrunde liegende Hardware oder CPU ist. Was ist der Kompromiss? Wahrscheinlichste Ausführungszeit.

+4

"Ein erweiterter Exponentenbereich zur Darstellung von Zwischenergebnissen" ist keine "Lizenz zur Berechnung Ihrer Gleitkommaberechnungen, wie sie auch wollen", und in der Praxis wird sogar bei "strictfp" -Berechnungen sogar eine nicht hilfreiche 8087-FPU verwendet. Nur dann ist etwas Vorsicht geboten. Siehe http://stackoverflow.com/questions/18496560/how-do-java-runtimes-targeting-pre-sse2-processors-implement-floating-point-basi –

17

Hier sind einige Referenzen:

  • Using strictfp (JDC Tech Tip)
  • jGuru: What is the strictfp modifier for? When would I consider using it?

    Im Grunde, was das alles hinausläuft, ist, ob Sie dafür, dass der Die Ergebnisse der Gleitkommaausdrücke in Ihrem Code sind schnell oder vorhersehbar. Wenn Sie beispielsweise die Antworten benötigen, die in Ihrem Code enthalten sind und Floating-Point-Werte verwenden, die für mehrere Plattformen konsistent sind, verwenden Sie strictfp.

  • strictfp - Java Glossary

    Gleitkomma-Hardware berechnet mit mehr Präzision und mit einem größeren Wertebereich als die Java-Spezifikation erfordert. Es wäre verwirrend, wenn einige Plattformen mehr Präzision als andere geben würden. Wenn Sie den Modifikator strictfp für eine Methode oder Klasse verwenden, generiert der Compiler Code, der sich streng an die Java-Spezifikation hält, um auf allen Plattformen identische Ergebnisse zu erzielen. Ohne strictfp ist es etwas laxer, aber nicht so locker, um die Guard Bits im Pentium zu verwenden, um 80 Bits Präzision zu geben.

  • Und schließlich die eigentliche Java Language Specification, §15.4 FP-strict Expressions:

    Innerhalb eines FP-strengen Ausdruck, alle Zwischenwerte müssen Elemente des Schwimmers Wert gesetzt oder Doppel Wert eingestellt werden, was bedeutet, dass die Die Ergebnisse aller FP-strikten Ausdrücke müssen diejenigen sein, die von der IEEE 754-Arithmetik für Operanden vorhergesagt werden, die mit Einzel- und Doppelformaten dargestellt werden. Innerhalb eines Ausdrucks, der nicht FP-strikt ist, wird einer Implementierung ein Spielraum eingeräumt, um einen erweiterten Exponentenbereich zu verwenden, um Zwischenergebnisse darzustellen; Der Nettoeffekt ist grob gesagt, dass eine Berechnung "die richtige Antwort" in Situationen erzeugen kann, in denen die ausschließliche Verwendung des Gleitkomma-Wertesatzes oder des Doppelwertsatzes zu einem Überlauf oder Unterlauf führen könnte.

Ich habe noch nie persönlich eine Verwendung für sie, though.

12

Wie die anderen Antworten erwähnt, führt dies dazu, dass die Fließkomma-Zwischenergebnisse der IEEE-Spezifikation entsprechen. Insbesondere können x86-Prozessoren Zwischenergebnisse mit unterschiedlicher Genauigkeit aus der IEEE-Spezifikation speichern. Die Situation wird komplizierter, wenn das JIT eine bestimmte Berechnung optimiert; Die Reihenfolge der Anweisungen könnte jedes Mal anders sein, was zu leicht unterschiedlichen Rundungen führt.

Der Overhead von strictfp wahrscheinlich sehr Prozessor-und JIT abhängig sein. Dieser Wikipedia-Artikel auf SSE2 scheint einige Einblicke in das Problem zu haben. Wenn also das JIT SSE-Anweisungen generieren kann, um eine Berechnung durchzuführen, scheint strictfp keinen Overhead zu haben.

In meinem aktuellen Projekt gibt es ein paar Stellen, an denen ich strictfp benutze. Es gibt einen Punkt, an dem potenzielle kosmische Strahlen aus Pixelwerten entfernt werden müssen. Wenn ein externer Forscher den gleichen Pixelwert und den gleichen kosmischen Strahl vor ihnen hat, sollten sie den gleichen resultierenden Wert wie unsere Software erhalten.

8
  • strictfp ist ein Modifikator, der 754.

  • Gleitkomma-Berechnungen gemäß IEEE

    schränkt dieses auf ganze Klasse verwendet werden können, wie "public class strictfp StrictFpModifierExample {}" oder Methode „public void Beispiel strictfp() ". Wenn es in der Klasse verwendet wird als alle Methoden werden folgen IEEE 754 und wenn auf Methode dann bestimmte Methode folgen IEEE 754.

  • Warum es verwendet wird ?? ::: Da verschiedene Plattformen haben unterschiedliche Fließkomma-Hardware, die mit mehr Präzision und Grea berechnet ter Bereich von Werten als die Java-Spezifikation erfordert, die auf diffrent diffrent Ausgabe erzeugen kann plateforms.so es die gleiche Leistung unabhängig von diffrent plateforms bestätigt

  • strictfp gewährleistet auch die Vorteile der Geschwindigkeit und Genauigkeit der erweiterter Präzision variabel nehmen Punktoperationen.

  • kein Nachteil mit diesem Begriff Es ist wir verwenden können, wenn wir Fließkommaberechnungen tun

  • Mein letzter Punkt ist --Was kurz IEEE IEEE754 ist 754 definiert Standardmethode für beide Fließkommaberechnungen und Speichern von Gleitkommawerten in einer einzigen (32-Bit, in Java-Floats verwendet) oder doppelten (64-Bit, in Java-Doubles) Genauigkeit. Sie definiert auch Normen für Zwischenberechnungen und für erweiterte Präzisionsformate.

2

strictfp ist ein Schlüsselwort, und kann als nicht Nicht Zugriffsmodifikator für Klassen oder ein Verfahren (aber nie Variablen) verwendet werden. Das Markieren einer Klasse als strictfp bedeutet, dass jeder Methodencode in der Klasse den IEEE 754-Standardregeln für Gleitkommawerte entspricht.

Ohne diesen Modifikator könnten sich in den Methoden verwendete Gleitkommawerte plattformabhängig verhalten. Damit können Sie vorhersagen, wie sich Ihre Gleitkommawerte verhalten, unabhängig von der zugrunde liegenden Plattform, auf der die JVM ausgeführt wird. Der Nachteil ist, dass, wenn die zugrunde liegende Plattform in der Lage ist, eine höhere Genauigkeit zu unterstützen, eine strictfp Methode nicht in der Lage sein wird, davon zu profitieren.

Wenn Sie nicht eine Klasse als strictfp deklarieren, können Sie immer noch strictfp Verhalten auf einer Methode-by-Methode Basis, durch ein Verfahren, wie strictfp erklärt.

~ SCJP Sun®Certified Programmierer für Java ™ 6 - Kathy Sierra & Bert Bates ~

15

hat alles mit einer Geschichte begann,

Wenn Java wurde von James Gosling, Herbert und Rest entwickelt sein Mannschaft. Sie hatten dieses verrückte Ding im Sinn namens Plattform Unabhängigkeit. Sie wollten eiche (Java) so viel besser machen, dass es auf jeder Maschine mit unterschiedlichem Befehlssatz genauso laufen würde, sogar mit verschiedenen Betriebssystemen. Aber es gab ein Problem mit Dezimalpunktnummern, die in Programmiersprachen auch als Fließkomma und Doppelpunkt bezeichnet werden. Einige Maschinen wurden auf Effizienz ausgerichtet, während Ruhe auf Genauigkeit ausgerichtet war. So hatten die späteren (genaueren) Maschinen eine Fließkommagröße von 80 Bits, während die früheren (effizienteren/schnelleren) Maschinen 64-Bit-Doppler hatten. Aber das war gegen die Kernidee, eine plattformunabhängige Sprache zu entwickeln.Dies kann auch zu einem Verlust von Präzision/Daten führen, wenn ein Code auf einer Maschine (mit einer doppelten 64-Bit-Größe) erstellt wird und auf einer anderen Art von Maschine (mit einer doppelten 80-Bit-Größe) ausgeführt wird.

Up-Sizing kann toleriert werden, aber Down-Sizing kann nicht sein. Also stießen sie auf ein Konzept von strictfp, d. H. strengen Fließkomma. Wenn Sie dieses Schlüsselwort mit einer Klasse/Funktion verwenden, haben seine Fließkomma- und Doppelpunkte eine konsistente Größe auf jedem Rechner. d.h. 32/64 Bit.

+1

strictfp wurde in Java 1.2 eingeführt. Das war viel später als wenn Eiche entworfen wurde. –

Verwandte Themen