Domanda

Qual è la differenza tra i diversi livelli di ottimizzazione in GCC?Supponendo che non mi interessi avere hook di debug, perché non dovrei utilizzare semplicemente il livello di ottimizzazione più alto a mia disposizione?richiede necessariamente un livello di ottimizzazione più elevato (ad es.dimostrabile) generare un programma più veloce?

È stato utile?

Soluzione

Sì, un livello più alto a volte può significare un programma con prestazioni migliori.Tuttavia, può causare problemi a seconda del codice.Ad esempio, la previsione dei rami (abilitata in -O1 e versioni successive) può interrompere programmi multi threading scritti male causando una condizione di competizione.L'ottimizzazione deciderà effettivamente qualcosa che è migliore di quello che hai scritto, il che in alcuni casi potrebbe non funzionare.

E a volte, le ottimizzazioni più elevate (-O3) non aggiungono alcun vantaggio ragionevole ma molte dimensioni extra.I tuoi test possono determinare se questo compromesso di dimensioni apporta un ragionevole guadagno di prestazioni per il tuo sistema.

Come nota finale, il progetto GNU compila tutti i suoi programmi su -O2 per impostazione predefinita, e -O2 è abbastanza comune altrove.

Altri suggerimenti

Generalmente livelli di ottimizzazione superiori a -O2 (Appena -O3 per gcc ma altri compilatori ne hanno di più alti) includono ottimizzazioni che possono aumentare la dimensione del codice.Ciò include cose come lo srotolamento del loop, molti inlining, il riempimento per l'allineamento indipendentemente dalle dimensioni, ecc.Altri compilatori offrono vettorizzazione e ottimizzazione interprocedurale a livelli superiori a -O3, così come alcune ottimizzazioni che possono migliorare molto la velocità a scapito della correttezza (ad esempio, utilizzando routine matematiche più veloci e meno accurate).Controlla i documenti prima di usare queste cose.

Per quanto riguarda le prestazioni, è un compromesso.In generale, i progettisti di compilatori cercano di ottimizzare queste cose in modo che non riducano le prestazioni del codice, quindi -O3 di solito aiuta (almeno nella mia esperienza) ma il tuo chilometraggio può variare.Non è sempre il caso che ottimizzazioni davvero aggressive di alterazione delle dimensioni migliorino le prestazioni (ad es.un inlining molto aggressivo può provocare l'inquinamento della cache).

Ho trovato un pagina web contenente alcune informazioni sui diversi livelli di ottimizzazione.Una cosa che ricordo di aver sentito da qualche parte è che l'ottimizzazione potrebbe effettivamente interrompere il tuo programma e questo può essere un problema.Ma non sono sicuro di quanto sia ancora un problema.Forse i compilatori di oggi sono abbastanza intelligenti da gestire questi problemi.

Nota a margine:

È piuttosto difficile prevedere esattamente quali bandiere verranno attivate a livello globale -O direttive sulla riga di comando di gcc per diverse versioni e piattaforme e tutta la documentazione sul sito GCC potrebbe diventare obsoleta rapidamente o non coprire gli interni del compilatore in modo sufficientemente dettagliato.

Ecco un modo semplice per verificare esattamente cosa succede sulla tua particolare configurazione quando usi uno dei -O bandiere e altro -f bandiere e/o loro combinazioni:

  1. Crea un file sorgente vuoto da qualche parte:
    touch dummy.c
  2. Eseguilo tramite il passaggio del compilatore come faresti normalmente, con all -O, -f e/o -m flag che utilizzeresti normalmente, ma aggiungendo -Q -v alla riga di comando:
    gcc -c -Q -v dummy.c
  3. Esamina l'output generato, magari salvandolo per un'esecuzione diversa.
  4. Cambia la riga di comando a tuo piacimento, rimuovi il file oggetto generato tramite rm -f dummy.o e rieseguire.

Inoltre, tieni sempre presente che, da un punto di vista purista, la maggior parte delle ottimizzazioni non banali generano codice "rotto" (dove rotto è definito come deviante dal percorso ottimale in casi limite), quindi scegliere se abilitare o meno un certo L'insieme di meccanismi di ottimizzazione a volte si riduce alla scelta del livello di correttezza per l'output del compilatore.Ci sono sempre (e ci sono attualmente) bug nell'ottimizzatore di qualsiasi compilatore: basta controllare la mailing list GCC e Bugzilla per alcuni esempi.L'ottimizzazione del compilatore dovrebbe essere utilizzata solo dopo aver effettivamente eseguito le misurazioni da allora

  • i guadagni derivanti dall'utilizzo di un algoritmo migliore sminuiranno qualsiasi guadagno derivante dall'ottimizzazione del compilatore,
  • non ha senso ottimizzare il codice che verrà eseguito ogni tanto,
  • se l'ottimizzatore introduce bug, è irrilevante la velocità con cui viene eseguito il codice.

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