Domanda

Sto riscontrando un problema davvero strano utilizzando GCC per ARM con le ottimizzazioni attivate.La compilazione della mia applicazione C ++ senza le ottimizzazioni produce un eseguibile che in runtime emette i risultati previsti.Non appena accendo le ottimizzazioni - cioè -O1 - la mia applicazione non riesce a produrre i risultati previsti.Ho provato per un paio di giorni a individuare il problema ma non ho idea.Ho eliminato eventuali variabili non inizializzate dal mio codice, ho corretto i punti in cui l'aliasing rigoroso poteva causare problemi ma non ho ancora i risultati adeguati.

Sto usando GCC 4.2.0 per ARM (il processore è un ARM926EJ-S) e esegue l'app su una distribuzione di Montavista Linux.

Di seguito sono riportati i flag che sto utilizzando:

-O1 -fno-unroll-loops fno-merge-constants -fno-omit-frame-pointer -fno-toplevel-reorder \
-fno-defer-pop -fno-function-cse -Wuninitialized -Wstrict-aliasing=3 -Wstrict-overflow=3 \
-fsigned-char -march=armv5te -mtune=arm926ej-s -ffast-math

Non appena rimuovo il flag -O1 e ricompilo/ricollego l'applicazione ottengo i risultati di output corretti.Come puoi vedere dai flag, ho provato a disabilitare qualsiasi ottimizzazione, pensavo che potesse causare problemi, ma ancora senza fortuna.

Qualcuno ha qualche indicazione su come potrei affrontare ulteriormente questo problema?

Grazie

È stato utile?

Soluzione

In generale, se dici "l'ottimizzazione interrompe il mio programma", è tuo al 99,9%. programma quello è rotto.Abilitazione solo delle ottimizzazioni scopre gli errori nel tuo codice.

Dovresti anche andarci piano con le opzioni di ottimizzazione.Solo in circostanze molto specifiche avrai bisogno di qualcos'altro oltre alle opzioni standard -O0, -O2, -O3 e forse -Os.Se ti senti Fare hai bisogno di impostazioni più specifiche di così, ascolta il mantra delle ottimizzazioni:

Misurare, ottimizzare, misurare.

Mai vai per "istinto" qui.Dimostrare che una determinata opzione di ottimizzazione non standard apporta vantaggi significativi alla tua applicazione, e capire perché (ovvero, capisci esattamente cosa fa quell'opzione e perché influisce sul tuo codice).

Questo non è un buon posto per navigare con gli occhi bendati.

E vedendo come usi l'opzione più difensiva (-O1), quindi disabiliti una mezza dozzina di ottimizzazioni e Poi aggiungi -ffast-math, mi porta a supporre che tu stia attualmente facendo proprio questo.

Beh, forse con un occhio solo.

Ma il punto è:Se l'attivazione dell'ottimizzazione danneggia il tuo codice, molto probabilmente è colpa del tuo codice.

MODIFICARE: Ho appena trovato questo nel manuale del GCC:

-ffast-math:Questa opzione non dovrebbe mai essere attivata da nessuna opzione -o poiché può comportare un output errato per i programmi che dipendono da un'implementazione esatta di regole/specifiche IEEE o ISO per le funzioni matematiche.

Questo dice, in sostanza, che your -O1 -ffast-math potrebbe effettivamente rompersi corretto codice.Tuttavia, anche se da portare via -ffast-math rimuove il tuo problema attuale, dovresti almeno avere un'idea Perché.Altrimenti potresti semplicemente scambiare il tuo problema Ora con un problema in un momento più scomodo Dopo (ad esempio, quando il tuo prodotto si rompe nella sede del tuo cliente).É davvero -ffast-math quello era il problema, o hai rotto il codice matematico scoperto di -ffast-math?

Altri suggerimenti

-ffast-math dovrebbe essere evitato se possibile. Basta usare -O1 per ora e rilasciare tutti gli altri interruttori di ottimizzazione. Se si vede ancora problemi, allora è il momento di avviare il debug.

Senza vedere il codice, è difficile ottenere più specifico di "probabilmente avete un bug".

Ci sono due scenari in cui consente ottimizzazioni cambia la semantica del programma:

  • c'è un bug nel compilatore, o
  • c'è un bug nel codice.

Il secondo è probabilmente il più probabile. In particolare, probabilmente contare su non definita da qualche comportamento nel vostro programma. Si basano su qualcosa che solo così capita di essere vero quando si compila con questo compilatore su questo computer con questi del compilatore bandiere, ma che isn' t garantito dal linguaggio. E così, quando si attiva ottimizzazioni, GCC non ha l'obbligo di conservare quel comportamento.

Mostraci il tuo codice. O passo attraverso di essa nel debugger fino ad arrivare al punto in cui le cose vanno male.

Non posso essere più preciso. Potrebbe essere un puntatore penzoloni, le variabili non inizializzate, rompendo le regole di aliasing, o anche solo facendo una delle tante cose che producono risultati non definiti (come i = i++)

Provate a fare un banco di prova minimo. Riscrivere il programma, eliminando le cose che non influenzano l'errore. E 'probabile che si scopre il bug da soli nel processo, ma se non lo fai, si dovrebbe avere un programma di esempio uno schermo che si possono posta.

Per inciso, se , come altri hanno speculato, è -ffast-math che causa il disturbo (cioè la compilazione con solo -O1 funziona bene), allora è probabile che avete un po 'di matematica in là si dovrebbe riscrivere comunque . E 'un po' di una semplificazione eccessiva, ma -ffast-math permette al compilatore di calcoli essenzialmente Riordino come si potrebbe astratti numeri matematici - anche se così facendo su hardware reale può causare risultati leggermente diversi da numeri in virgola mobile non sono esatti. Basandosi su questo tipo di virgola mobile dettaglio è probabile che sia non intenzionale.

Se si vuole comprendere il bug, un minimo di test-case è fondamentale in ogni caso.

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