|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Junior Member
Iscritto dal: Feb 2011
Messaggi: 13
|
controllo precisione fpu
Ciao,
Per un'applicazione geometrica scritta in c++ utilizzo due piattaforme, una è un laptop con: - windows - compilatore gcc - processori intel l'altra è un cluster con: - linux - compilatore gcc - processori intel Il problema è che, pur essendo il codice lo stesso, i risultati numerici sono (leggermente) diversi. Ho provato a inserire il codice seguente, che dovrebbe consentire di controllare la precisione della fpu: void set_fpu (unsigned int mode) { asm ("fldcw %0" : : "m" (*&mode)); } set_fpu (0x27F); /* use double-precision rounding */ Purtroppo non funziona :-( Avete qualche idea? Grazie, Alex |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
|
Prova in fase di compilazione a disabilitare eventuali ottimizzazioni del processore.
Se entrambe le piattafome supportano SSE prova ad usare queste flags "-O2 -march=i686 -mfpmath=sse -msse2" oppure potresti usare "-O2 -march=i686 -mfpmath=387" Se non riesci a risolvere prova a giochicchiare con le flags di compilazione, in particolare per disabilitare tutte le ottimizzazioni : "-O0 -march=i386 -mtune=i386 -mfpmath=387" Usare la STESSA versione di GCC potrebbe aiutare ad avere risultati consistenti, perchè magari il codice generato è leggermente diverso Ciao PS= ovviamente per usare la doppia precisione assicurati di stare usando dei double nel tuo programma
__________________
GPU Compiler Engineer Ultima modifica di AnonimoVeneziano : 31-08-2011 alle 16:21. Motivo: Mancava una flag per le SSE :p |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Verifica quali ottimizzazioni relative all'fpu sono abilitate (di default?) nei due ambienti.
In particolare se vuoi rendere la cosa piu' portabile, devi forzare un comportamento conforme allo standard (al prezzo di performance potenzialmente piu' basse). Prova a dare una occhiata alle varie flag relative di gcc. Un "sospetto" potrebbe essere -fexcess-precision visto che di default con nel caso di sse usa la precisione definita dallo standard, mentre nel caso dell'fpu no.
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele |
|
|
|
|
|
#4 |
|
Junior Member
Iscritto dal: Feb 2011
Messaggi: 13
|
@ anonimo veneziano: "PS= ovviamente per usare la doppia precisione assicurati di stare usando dei double nel tuo programma!". In realtà ci sono anche parecchi float, ma non capisco perchè questo fatto dovrebbe c'entrare. A me non interessa che i risultati siano precisi, io voglio soltanto che venga fuori lo stesso risultato.
@ Marco. Non posso disabilitare le ottimizzazioni, la versione sul cluster dev’essere più veloce possibile, mentre l’altra mi serve per il debug. Comunque l’unico flag che utilizzo in compilazione è –O3. In ogni caso adesso sto cercando di usare double dappertutto, poi provo a rimettere il codice di controllo della FPU e vediamo. |
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Quote:
Magari scopri che sono quelle sulla tua macchina ad essere colpevoli (esempio: magari il cluster utilizza istruzioni SSE con precisione 64 bit, mentre il tuo pc utilizza l'FPU, con una precisione di 80 bit per i dati intermedi)
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele Ultima modifica di marco.r : 01-09-2011 alle 14:06. |
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
|
Come ha detto marco se usi ottimizzazioni diverse per le due macchine i risultati possono essere diversi. In particolare devi assicurarti che entrambe le macchine usino le stesse unità floating point (o entrambi quelle SSE o entrambi la FPU 387) perchè la FPU 387 usa una precisione interna a 80bit e poi per farlo stare in un double il risultato viene riscalato a 64 bit, mentre la FPU SSE utilizza la precisione a 64 bit per i calcoli interni e questa cosa può creare risultati differenti se su una macchina usi 387 e sull'altra SSE .
Inoltre se non ti interessa la precisione, ma preferisci la velocità allora potresti pensare di usare l' ottimizzazione "-ffast-math" che più di qualsiasi altra ottimizzazione velocizza i calcoli con la FPU a scapito però della compliance con lo standard IEEE per i calcoli in virgola mobile. Se usando "-ffast-math" non si rompe niente allora sei a cavallo
__________________
GPU Compiler Engineer |
|
|
|
|
|
#7 |
|
Junior Member
Iscritto dal: Feb 2011
Messaggi: 13
|
Grazie per le risposte ragazzi, sto facendo delle prove. A proposito, al compilatore microsoft visual studio l'istruzione:
asm ("fldcw %0" : : "m" (*&mode)); non piace. Non gli piace nemmeno: _asm ("fldcw %0" : : "m" (*&mode)); Sapete qual'è la versione giusta? |
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
|
Quote:
http://msdn.microsoft.com/en-gb/library/e9b52ceh.aspx
__________________
GPU Compiler Engineer |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 19:55.




















