Il codice più grande è ancora più veloce

5

Quando si compila il codice C con gcc , ci sono ottimizzazioni del compilatore, alcune che limitano le dimensioni del codice e altre creano codice veloce.

Dal flag -S , vedo che -O2/03 genera più assembly del codice -Os . In che modo il montaggio è ancora più veloce di un assemblaggio inferiore?

    
posta inixsoftware 30.09.2013 - 02:58
fonte

2 risposte

6

Su un processore moderno, di solito ci sono diversi modi per ottenere il risultato specificato in un linguaggio di livello superiore (come C). Queste soluzioni possono avere diversi compromessi tra la dimensione del codice e la velocità a causa di diversi fattori.

  • Non tutte le istruzioni di assemblaggio richiedono lo stesso tempo per l'esecuzione. Ad esempio, è possibile che un particolare risultato possa essere ottenuto con 2 istruzioni che richiedono 10 cicli di clock ciascuna da eseguire, o con 6 istruzioni che richiedono 3 cicli di clock ciascuna. La differenza qui può essere dovuta al fatto che queste due lunghe istruzioni duplicano parte del lavoro che il compilatore ha evitato usando le 6 brevi istruzioni.
  • Su un processore moderno, fa una grande differenza nella velocità di esecuzione se l'istruzione successiva è già presente nella cache o se deve provenire dalla memoria principale. Questo effetto è più visibile con le istruzioni di ramificazione, perché rendono più difficile stabilire quale sarà l'istruzione successiva. Spesso, i compilatori cercheranno di compensare questi effetti srotolando (parte di) un ciclo in un blocco ripetuto di istruzioni per ridurre i costi di ramificazione / salto.
risposta data 30.09.2013 - 08:37
fonte
3

Bene, il più delle volte il compilatore genera più istruzioni in modo che meno di loro siano eseguite in una determinata esecuzione. Generalmente generando codice specifico per casi diversi:

  • Loop srotolamento. Il salto è fatto solo in ogni n (di solito 8) iterazioni.
  • Inlining della funzione. Salva la chiamata, restituisce, copia gli argomenti e manipola gli stack.

L'altra cosa è che alcune istruzioni richiedono più tempo di altre. Soprattutto le condizioni difficili da prevedere possono essere notevolmente più lente. Tuttavia, sia le chiamate che i loop sono comuni e il predittore li gestisce bene.

L'altra cosa è la memoria cache, ma qui le cose non sono così chiare. Le cache funzionano meglio quando il codice viene letto linearmente (le funzioni sono in linea), ma ha anche dimensioni limitate, quindi una porzione più grande di codice piccolo verrà memorizzata nella cache.

    
risposta data 30.09.2013 - 09:56
fonte

Leggi altre domande sui tag