Ottimizzazioni del compilatore

di il
5 risposte

Ottimizzazioni del compilatore

Ciao Forum,

Come ho avuto altre volte occasioni di dire, ho fatto i miei primi passi circa trent'anni fa e poi tantissime nozioni non le ho più verificate o aggiornate. Sui vari 8088 gli effetti di un codice scritto male si vedevano perché essendo CPU lentissime si poteva avvertire l'effetto anche "a naso" coi tempi di esecuzione. Oggi ho paura che con il miglioramento dei compilatori molti miei timori non esistano più e viceversa, molte cose che mi paiono valide non lo sono e vengono mascherate dalla velocità di esecuzione. Vi espongo le mie perplessità come semplice punto di partenza per dare la chiave di lettura della mia domanda in fondo.

1) Effettiva allocazioni delle variabili. Ho sempre usato variabili nominate come "dummy" e simili riusandole se ero certo - sottolineo, certo - che venissero usate in zone separate della funzione. Di recente mi è stato detto che questa preoccupazione è infondata perché si possono tranquillamente dichiarare tutte quelle che servono, il compilatore se ne accorge e ne alloca solo una trasformandole di fatto in alias intelligenti. Suppongo sia vero, mi pare ragionevole.

2) Uso di campi annidati nelle strutture. Quando ho qualcosa del tipo (((ptr->campo1)->campo2)->campo3[index]) l'istinto mi dice che è una cosa pesante per l'indirizzamento indiretto annidato. Se so di usare questo tipo di valori una volta sola ovviamente lo faccio, altrimenti ne metto il risultato in una variabile di appoggio e la leggo più volte. Anche qui posso supporre che il compilatore se ne accorga e usi una variabile temporanea trasparente all'utente. Lo stesso in casi classici come "if( str == 'a' || str == 'c' )" ho sempre la tentazione di assegnare "ch = str" e lavorare su "ch".

Ecco, le mie domande sono: nella vostra esperienza, 1) cosa - se c'è - si è dimostrata una vostra preoccupazione infondata e 2) viceversa, cosa credevate fosse ragionevole e poi avete scoperto di no? E poi, esiste materiale dove possa farmi una panoramica sul come scrivere bene dal punto di vista dell'efficienza del codice? Chiaramente non parlo dell'uso di una mappa vs vettore quindi non mi riferisco agli algoritmi ma proprio agli accorgimenti per non fare sciocchezze.

grazie!

5 Risposte

  • Re: Ottimizzazioni del compilatore

    Non sono né un programmatore esperto, né ho mai programmato "seriamente" in assembly, però penso che qualcosa possa dire nel risponderti.

    1/2) Non ho ancora mai fatto intensive ottimizzazioni low-level, e per questo non so veramente molto quello che succede nel compilatore. Una cosa di cui mi preoccupavo molto, e che a pensarlo ora ovviamente è stupida, è che dichiaravo sempre dove possibile le variabili dello stack con il minor numero di byte size possibile (contatori di 1 byte nei for, massimo 2 byte per le altre variabil), per poi scoprire che tanto il compilatore per fattori di alignment e calcolo comunque minimo mi alloca 4 byte sempre e comunque (o che comunque passa al prossimo multiplo di 4).

    Ti consiglio di vederti i video della CppCon, li trovi qui su youtube: https://www.youtube.com/user/CppCon/video . Molti video si concentrano sull'ottimizzazione, anche "micro", dal punto di vista di cache, ALU, branch-prediction, etc... (alcuni commentano e discutono anche sul codice assembly generato). Ti consiglio soprattutto i talk e presentazioni (anche non della CppCon) di Andrei Alexandrescu, è veramente bravo, spiega chiaramente concetti e ottimizzazioni complicate, ed è anche molto simpatico (ogni tanto mi rivedo il suo talk sui std::allocator non per ripasso dei concetti ma per ridere di come prende in giro lo standard c++/programmatori delle librerie ).
    Ovviamente se vai su google troverai a migliaia di thread/blog dove programmatori discutono su ottimizzazioni e strutture dati ottimali.

    Voglio poi condividere con te (e con anche gli altri utenti del forum) questa piccola perla: https://gcc.godbolt.org . Compilatore C++ che mostra il codice generato, tutto sul browser, e si può personalizzare con il compilatore desiderato e anche con i suoi parametri. Spesso lo ho usato per curiosità per vedere come funziona e vengono implementate certe feature del c++ (virtual class, exception, ...)
  • Re: Ottimizzazioni del compilatore

    Ti consiglio anche di spulciare il sito di Agner Fog (avviso: il manuale che propone sull'ottimizzazione è un po' "corposo" )
    http://www.agner.org/optimize
  • Re: Ottimizzazioni del compilatore

    @Alan_Reloaded: ti stai facendo dei problemi inesistenti.

    1) le problematiche che hai elencato sono trattate tranquillamente dal compilatore
    2) ma non solo, in caso di elaboazioni su vettori, ad esempio, il compilatore e' sufficientemente intelligente da utilizzare le funzioni SSE (Streaming SIMD Extensions)

    A meno che l'implementazione non sia stata scritta da una persona con 0-esperienza, nel 99.9999% dei casi i problemi di cattive performance sono legate all'utilizzo di strutture dati sbagliate, ad algoritmi inefficienti, errori nella gestione della allocazione/deallocazione della memoria, e soprattutto ad IO eccessivo (nessuna bufferizzazione).

    In generale il collo di bottiglia, nell'esecuzione di un'applcazione, NON SI TROVA dove uno suppone sia, ma sta' da tutt'altra parte

    Se la tua applicazione ha dei problemi di performance, ci sono i memory/performance profilers che instrumentano il codice, raccolgono statistiche durante l'esecuzione, e le salvano al termine dell'esecuzione del codice.
    L'il problema lo puoi identificare analizzando il report che il profiler genera.
  • Re: Ottimizzazioni del compilatore

    Grazie a tutti per le risposte; ho seguito i links e i PDF sembrano interessanti con un sacco di cose che ovviamente non sapevo. Tra me e me mi fa piacere vedere che le linee guida fondamentali più o meno sono quelle che conoscevo
  • Re: Ottimizzazioni del compilatore

    Sull'ottimizzazione dovresti studiare la prima parte di questa bibliografia.
Devi accedere o registrarti per scrivere nel forum
5 risposte