Quando dovrei usare la parola chiave “strictfp” in java?

Ho cercato cosa fare, ma qualcuno ha davvero un esempio di quando si usa la parola chiave strictfp in Java? Qualcuno ha effettivamente trovato un uso per questo?

Ci sarebbero effetti collaterali solo nel metterlo in tutte le operazioni in virgola mobile?

Strictfp garantisce di ottenere esattamente gli stessi risultati dai calcoli in virgola mobile su ogni piattaforma. Se non si utilizza strictfp, l’implementazione JVM è libera di utilizzare una precisione extra laddove disponibile.

Dalla JLS :

All’interno di un’espressione rigida FP, tutti i valori intermedi devono essere elementi del valore float impostato o del doppio valore, il che implica che i risultati di tutte le espressioni FP-strict devono essere quelli previsti dall’aritmetica IEEE 754 su operandi rappresentati utilizzando formati singoli e doppi . All’interno di un’espressione che non è FP-strict, è concesso un certo margine per un’implementazione che utilizza un intervallo di esponente esteso per rappresentare risultati intermedi; l’effetto netto, in parole povere, è che un calcolo potrebbe produrre “la risposta corretta” in situazioni in cui l’uso esclusivo del valore float impostato o del doppio valore potrebbe risultare in overflow o underflow.

In altre parole, si tratta di assicurarsi che Write-Once-Run-Anywhere in realtà significhi Write-Once-Get-Equally-Wrong-Results-Everywhere .

Con strictfp i risultati sono portabili, senza di essi è più probabile che siano precisi.

Wikipedia in realtà ha un buon articolo su questo argomento qui , con un link alle specifiche Java.

Leggendo tra le righe, l’implicazione è che se non si specifica strictfp , allora il compilatore JVM e JIT hanno la licenza per calcolare i calcoli in virgola mobile come vogliono. Nell’interesse della velocità, molto probabilmente delegheranno il calcolo al processore. Con strictfp on, i calcoli devono essere conformi agli standard aritmetici IEEE 754, il che, in pratica, probabilmente significa che la JVM eseguirà il calcolo.

Allora, perché vorresti usare strictfp ? Uno scenario che posso vedere è in un’applicazione distribuita (o gioco multiplayer) in cui tutti i calcoli in virgola mobile devono essere deterministici, indipendentemente dall’hardware o dalla CPU sottostante. Qual è il trade-off? Molto probabilmente il tempo di esecuzione.

Ecco alcuni riferimenti:

  • Utilizzando strictfp (Suggerimento tecnico JDC)
  • jGuru: A cosa serve il modificatore strictfp? Quando dovrei considerare di usarlo?

    Fondamentalmente, tutto ciò che si riduce è se ti interessi o meno che i risultati delle espressioni in virgola mobile nel tuo codice siano veloci o prevedibili. Ad esempio, se hai bisogno delle risposte strictfp con il tuo codice che utilizza valori a virgola mobile per essere coerenti su più piattaforms, usa strictfp .

  • strictfp – Glossario Java

    L’hardware in virgola mobile calcola con maggiore precisione e con un intervallo di valori maggiore rispetto a quanto richiesto dalla specifica Java. Sarebbe fonte di confusione se alcune piattaforms offrissero più precisione di altre. Quando si utilizza il modificatore strictfp su un metodo o una class, il compilatore genera codice che aderisce rigorosamente alle specifiche Java per risultati identici su tutte le piattaforms. Senza strictfp , è leggermente più rilassato, ma non così rilassato da utilizzare i bit di guardia nel Pentium per fornire 80 bit di precisione.

  • E infine l’effettiva specifica del linguaggio Java, §15.4 Espressioni FP-severe :

    All’interno di un’espressione rigida FP, tutti i valori intermedi devono essere elementi del valore float impostato o del doppio valore, il che implica che i risultati di tutte le espressioni FP-strict devono essere quelli previsti dall’aritmetica IEEE 754 su operandi rappresentati utilizzando formati singoli e doppi . All’interno di un’espressione che non è FP-strict, è concesso un certo margine per un’implementazione che utilizza un intervallo di esponente esteso per rappresentare risultati intermedi; l’effetto netto, in parole povere, è che un calcolo potrebbe produrre “la risposta corretta” in situazioni in cui l’uso esclusivo del valore float impostato o del doppio valore potrebbe risultare in overflow o underflow.

Non ho mai avuto personalmente un uso per questo, però.

Tutto è iniziato con una storia,

Quando java è stato sviluppato da James Gosling, Herbert e il resto della sua squadra. Avevano in mente questa cosa pazza chiamata indipendenza dalla piattaforma . Volevano rendere la quercia (Java) molto meglio che funzionasse esattamente allo stesso modo su qualsiasi macchina che avesse set di istruzioni differenti, anche con sistemi operativi diversi. Ma c’era un problema con i numeri decimali, conosciuti anche come virgola mobile e doppio nei linguaggi di programmazione. Alcune macchine sono state progettate per ottimizzare l’efficienza mentre il resto mirava alla precisione. Quindi, le macchine successive (più accurate) avevano una dimensione del punto mobile di 80 bit mentre le macchine precedenti (più efficienti / più veloci) avevano 64 bit di doppio. Ma questo era contrario all’idea centrale di build un linguaggio indipendente dalla piattaforma. Inoltre, questo potrebbe portare alla perdita di precisione / dati quando un codice viene creato su una macchina (con una dimensione doppia di 64 bit) ed eseguito su un altro tipo di macchina (con una dimensione doppia di 80 bit).

Up-Sizing può essere tollerato ma Down-Sizing non può essere. Quindi, si imbattono in un concetto di strictfp cioè in virgola mobile . Se si utilizza questa parola chiave con una class / funzione, il suo punto mobile e il doppio avranno una dimensione consistente su qualsiasi macchina. vale a dire 32/64 -bit rispettivamente.

Come le altre risposte menzionate, i risultati del floating point intermedio sono conformi alle specifiche IEEE. In particolare, i processori x86 possono memorizzare risultati intermedi con precisione diversa dalle specifiche IEEE. La situazione diventa più complicata quando il JIT ottimizza un particolare calcolo; l’ordine in cui le istruzioni potrebbero essere diverse ogni volta con un arrotondamento leggermente diverso.

Il sovraccarico sostenuto da strictfp rischia di essere molto dipendente dal processore e dal JIT. Questo articolo su wikipedia su SSE2 sembra avere qualche idea del problema. Quindi, se il JIT può generare istruzioni SSE per eseguire un calcolo, sembra che strictfp non avrà alcun sovraccarico.

Nel mio attuale progetto ci sono alcuni posti dove uso strictfp. C’è un punto in cui i potenziali raggi cosmici devono essere rimossi dai valori dei pixel. Se alcuni ricercatori esterni hanno lo stesso valore in pixel e il raggio cosmico di fronte a loro, dovrebbero ottenere lo stesso valore risultante del nostro software.

  • strictfp è un modificatore che limita i calcoli in virgola mobile come da IEEE 754.

  • Questo può essere usato su tutta la class come “public strictfp class StrictFpModifierExample {}” o sul metodo “public strictfp void example ()”. Se viene usato in class, tutti i metodi seguiranno IEEE 754 e se usato sul metodo allora un metodo particolare seguire IEEE 754.

  • Perché è usato ?? ::: Poiché piattaforms diverse hanno hardware in virgola mobile diverso che calcola con maggiore precisione e un più ampio intervallo di valori rispetto alle specifiche java che possono produrre output diffrenti su plateform diffrent.so conferma la stessa uscita indipendentemente da diffrent plateforms

  • strictfp garantisce inoltre di sfruttare la velocità e la precisione delle operazioni di virgola mobile di precisione estesa.

  • Non c’è svantaggio con questa parola chiave che possiamo usare quando facciamo calcoli in virgola mobile

  • Il mio ultimo punto è: Che cosa è IEEE754 in breve IEEE 754 definisce il metodo standard per entrambi i calcoli in virgola mobile e la memorizzazione di valori in virgola mobile in uno singolo (a 32 bit, utilizzato in Java float) o doppio (a 64 bit, utilizzato in Java raddoppia). Definisce anche le norme per i calcoli intermedi e per i formati di precisione estesa.

strictfp è una parola chiave e può essere usato come modificatore non di accesso per classi o metodi (ma mai variabili). Contrassegnare una class come strictfp significa che qualsiasi codice di metodo nella class sarà conforms alle regole standard IEEE 754 per i punti mobili.

Senza quel modificatore, i punti fluttuanti usati nei metodi potrebbero comportarsi in modo dipendente dalla piattaforma. Con esso puoi prevedere come si comportano i tuoi punti mobili indipendentemente dalla piattaforma sottostante su cui è in esecuzione la JVM. Lo svantaggio è che se la piattaforma sottostante è in grado di supportare una maggiore precisione, un metodo strictfp non sarà in grado di sfruttarlo.

Se non si dichiara una class come strictfp , è comunque ansible ottenere il comportamento strictfp su base metodo per metodo, dichiarando un metodo come strictfp .

~ SCJP Sun®Certified Programmer per Java ™ 6 – Kathy Sierra e Bert Bates ~

L’esempio di seguito può aiutare a capire ciò in modo più chiaro: In java ogni volta che stiamo usando la ricerca di informazioni precise per ogni operazione, ad esempio se facciamo il doppio num1 = 10e + 102; doppio num2 = 8e + 10; risultato = num1 + num2;

  The output will be so long and not precise, becasue it is precissed by the hardware eg JVM and JIT has the license as long as we dont have specify it Strictfp Marking it Strictfp will make the result Uniform on every hardware and platform, because its precised value will be same One scenario I can see is in a distributed application (or multiplayer game) where all floating-point calculations need to be deterministic no matter what the underlying hardware or CPU is.