Come reagisce un compilatore ottimizzante a un programma con cicli annidati?

1

Dì che hai un sacco di loop annidati.

public void testMethod() {
    for(int i = 0; i<1203; i++){
                //some computation
        for(int k=2; k<123; k++){
                        //some computation
            for(int j=2; j<12312; j++){
                                //some computation
                for(int l=2; l<123123; l++){
                                        //some computation
                    for(int p=2; p<12312; p++){
                            //some computation
                    }
                }
            }
        }
    }

}

Quando il codice sopra raggiunge lo stadio in cui il compilatore cercherà di ottimizzarlo (credo che sia quando il linguaggio intermedio deve essere convertito in codice macchina?), cosa cercherà di fare il compilatore? C'è qualche ottimizzazione significativa che avverrà?

Comprendo che l'ottimizzatore interromperà i loop mediante fissione del ciclo . Ma questo è solo per ciclo, no? Quello che intendo con la mia domanda è che prenderà qualsiasi azione esclusivamente basata sul vedere i loop annidati? O semplicemente ottimizzerà i loop uno per uno?

Se la VM Java complica la spiegazione, supponiamo che si tratti di codice C o C ++.

    
posta DSF 29.05.2014 - 12:55
fonte

1 risposta

2

Un compilatore di ottimizzazione generalmente funziona sulla base del fatto che il ciclo più interno è l'unico che valga la pena. Le strategie per l'ottimizzazione dei loop includono srotolamento, vettorizzazione, sollevamento (calcoli fuori dal ciclo) e così via. Può anche cambiare il codice se può determinare che il ciclo terminerà presto o non lo farà affatto. Nessuno di questi è specifico per i cicli nidificati.

Le uniche ottimizzazioni che conosco sono specifiche per i cicli annidati sono queste.

  1. Scambio / inversione del ciclo. for(x...){for(y...){...}} può essere invertito in for(y...){for(x...){...}} se il compilatore può determinare che è (a) equivalente (b) più veloce o (c) può essere reso più veloce.
  2. La vettorizzazione applicata al loop interno può essere estesa per vettorizzare loop multipli, a seconda del set di istruzioni disponibile.
  3. Se il ciclo interno può essere srotolato o vettorizzato o cancellato, il ciclo successivo diventa il ciclo interno ed è soggetto alle stesse ottimizzazioni.
  4. Se un'espressione può essere sollevata da un loop interno, può forse essere sollevata ulteriormente.

Non è facile sapere quali compilatori implementano attualmente quali di questi. So che i compilatori Fortran sono stati i primi implementatori di vettorializzazioni aggressive su macchine come Cyber e Cray, ma non sono in contatto con questo ora. Adesso guardi i compilatori per il targeting di GPU.

    
risposta data 31.05.2014 - 04:36
fonte

Leggi altre domande sui tag