Domanda

La mia applicazione sta generando diversi valori in virgola mobile quando la compilo in modalità di rilascio e in modalità di debug. L'unico motivo che ho scoperto è il salvataggio di un log di traccia binario e quello dalla build di rilascio è sempre leggermente fuori dalla build di debug, sembra che i due bit inferiori dei valori float a 32 bit siano diversi circa 1/2 dei casi.

Considereresti questa "differenza" essere un bug o ci si aspetterebbe questo tipo di differenza. Sarebbe un bug del compilatore o un bug della libreria interna.

Ad esempio:

LEFTPOS and SPACING are defined floating point values.
float def_x;
int xpos;

def_x = LEFTPOS + (xpos * (SPACING / 2));

Il problema riguarda il compilatore X360.

È stato utile?

Soluzione

La modalità di rilascio può avere un diverso set di strategie FP. Esistono diverse modalità aritmetiche in virgola mobile a seconda del livello di ottimizzazione desiderato. MSVC, ad esempio, ha modalità rigorose, veloci e precise.

Altri suggerimenti

So che su PC i registri in virgola mobile sono larghi 80 bit. Quindi, se un calcolo viene eseguito interamente all'interno della FPU, si ottiene il vantaggio di 80 bit di precisione. D'altra parte, se un risultato intermedio viene spostato in un registro normale e viceversa, viene troncato a 32 bit, il che dà risultati diversi.

Ora considera che una build di rilascio avrà ottimizzazioni che mantengono risultati intermedi nei registri FPU, mentre una build di debug probabilmente ingenuamente copia risultati intermedi avanti e indietro tra memoria e registri - e lì hai la tua differenza di comportamento.

Non so se ciò accada anche su X360 o meno.

Ho aiutato un collega a trovare un interruttore del compilatore che era diverso nelle versioni di rilascio rispetto al debug che causava le sue differenze.

Dai un'occhiata a / fp (Specifica il virgola mobile comportamento) .

Non è un bug. Qualsiasi aggiornamento in virgola mobile ha una certa imprecisione. In modalità Rilascio, l'ottimizzazione cambierà l'ordine delle operazioni e otterrai un risultato leggermente diverso. La differenza dovrebbe essere piccola, però. Se è grande potresti avere altri problemi.

Oltre alle diverse modalità a virgola mobile che altri hanno sottolineato, SSE o ottimizzazioni vettoriali simili possono essere attivate per il rilascio. La conversione dell'aritmetica in virgola mobile da registri standard a registri vettoriali può avere un effetto sui bit inferiori dei risultati, poiché i registri vettoriali saranno generalmente più stretti (meno bit) rispetto ai registri standard a virgola mobile.

Non un bug. Questo tipo di differenza è prevedibile.

Ad esempio, alcune piattaforme hanno registri float che usano più bit di quanti sono memorizzati nella memoria, quindi mantenere un valore nel registro può produrre un risultato leggermente diverso rispetto alla memorizzazione in memoria e al nuovo caricamento dalla memoria.

Questa discrepanza potrebbe benissimo essere causata dall'ottimizzazione del compilatore, che in genere viene eseguita in modalità di rilascio, ma non in modalità di debug. Ad esempio, il compilatore può riordinare alcune delle operazioni per accelerare l'esecuzione, il che può plausibilmente causare una leggera differenza nel risultato in virgola mobile.

Quindi, direi molto probabilmente che non è un bug. Se sei davvero preoccupato per questo, prova ad attivare l'ottimizzazione nella modalità Debug.

Come altri menzionati, i registri in virgola mobile hanno una precisione maggiore rispetto ai float, quindi l'accuratezza del risultato finale dipende dall'allocazione del registro.

Se hai bisogno di risultati coerenti, puoi rendere le variabili volatili, il che si tradurrà in risultati più lenti, meno precisi, ma coerenti.

Se imposti uno switch del compilatore che consente al compilatore di riordinare le operazioni in virgola mobile, ad es. / fp: veloce - quindi ovviamente non è un bug.

Se non hai impostato uno di questi switch, allora è un bug: gli standard C e C ++ non consentono ai compilatori di riordinare le operazioni senza la tua autorizzazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top