Dire che ho alcune funzioni, ciascuna di circa due semplici righe di codice e si chiamano in questo modo: A
chiamate B
chiamate C
chiamate D
... chiamate K
. (Quindi in pratica si tratta di una lunga serie di brevi chiamate di funzione). Quanto saranno profondi i compilatori di solito nella struttura delle chiamate per integrare queste funzioni?Quanto sono profonde le funzioni inline dei compilatori?
risposta
La domanda non è significativa.
Se ci pensate inline, e le sue conseguenze, vi renderete conto che:
- Evita una chiamata di funzione (con tutta la regolazione registro risparmio/telaio)
- espone più contesto per l'ottimizzatore (negozi morti, codice morto, comune elimintation sub-espressione ...)
- codice duplicati (gonfiore della cache istruzioni e la dimensione dell'eseguibile, tra le altre cose)
Quando decidere sia in linea che no, il compilatore esegue quindi un bilanciamento tra il potenziale rigonfiamento creato e il guadagno di velocità previsto. Questo atto di bilanciamento è influenzato dalle opzioni: per gcc -O3
significa ottimizzare per la velocità mentre -Oz
significa ottimizzare per la dimensione, in linea hanno comportamenti quasi opposti!
Pertanto, ciò che importa non è il "livello di nidificazione", è il numero di istruzioni (eventualmente ponderato in quanto non tutte sono create uguali).
Ciò significa che una semplice funzione di inoltro:
int foo(int a, int b) { return foo(a, b, 3); }
è essenzialmente "trasparente" dal punto di vista inlining.
D'altra parte, è improbabile che una funzione che conta un centinaio di righe di codice venga attivata. Tranne che le funzioni gratuite static
chiamate solo una volta sono quasi sistematicamente in linea, in quanto non crea alcuna duplicazione in questo caso.
Da questi due esempi che ottenere la sensazione di come le euristiche si comportano:
- meno le istruzioni della funzione hanno, meglio è per inling
- meno spesso viene chiamato, meglio è per inlining
Dopo di che, sono parametri si dovrebbe essere in grado di impostare di influenzare un modo o nell'altro (MSVC come __force_inline
che allude fortemente alla inling, gcc
quanto -finline-limit
bandiera per "sollevare" il tresh vecchio sul conteggio di istruzioni, ecc ...)
per la tangente: ne sai di parziale inlining?
È stato introdotto in gcc in 4.6. L'idea, come suggerisce il nome, è di integrare parzialmente una funzione. Principalmente, per evitare il sovraccarico di una chiamata di funzione quando la funzione è "sorvegliata" e può (in alcuni casi) tornare quasi immediatamente.
Ad esempio:
void foo(Bar* x) {
if (not x) { return; } // null pointer, pfff!
// ... BIG BLOC OF STATEMENTS ...
}
void bar(Bar* x) {
// DO 1
foo(x);
// DO 2
}
potrebbe ottenere "ottimizzato", come:
void [email protected](Bar* x) {
// ... BIG BLOC OF STATEMENTS ...
}
void bar(Bar* x) {
// DO 1
if (x) { [email protected](x); }
// DO 2
}
Naturalmente, ancora una volta le euristiche per inlining si applicano, ma applicare più discriminately!
E, infine, a meno che non si utilizza WPO (intero programma di ottimizzazione) o LTO (Link Tempo Optimization), le funzioni possono essere inline solo se la loro definizione è nello stesso TU (unità di traduzione) che il sito di chiamata.
In genere non lo faccio, ma penso che dovrei cambiare la risposta accettata. :) Non conoscevo la funzione di inlining parziale né di inlining in base al numero di chiamate. Grazie per i dettagli. –
Ho visto i compilatori inline più di 5 funzioni in profondità. Ma a un certo punto, diventa fondamentalmente un compromesso spazio-efficienza che il compilatore fa. Ogni compilatore è diverso in questo aspetto. Visual Studio è molto conservativo con inlining. GCC (sotto -O3) e l'Intel Compiler amano in linea ...
IIRC in gcc dipende da un approssimativo "conteggio delle istruzioni" per la funzione che è in linea (ovvero quanto tempo è effettivamente); il livello di nidificazione non gioca un ruolo da quello che ho letto nei documenti ('-finline-limit' e amici), nel senso che la funzione della lunghezza 10 sarà in linea proprio come 5 + nidificata 5. – eudoxos
Se le funzioni sono chiamate solo una volta non c'è motivo di evitare la linea. GCC sarà anche in linea in modo aggressivo se il feedback del profilo dice che dovrebbe. –
@Zan Lynx: Questo è per lo più corretto. Ci sono alcuni casi, dove è meglio non in linea. Se la funzione si trova in un ciclo critico delle prestazioni e viene chiamata raramente (come un gestore trap), è meglio non in linea, in modo da mantenere le dimensioni del codice del ciclo ridotte. (questo a volte ti permette di usare salti corti invece di salti lunghi) – Mysticial
- 1. Ci sono funzioni inline in java?
- 2. Le funzioni definite nelle intestazioni sono garantite come inline?
- 3. Perché le funzioni in linea sono autorizzate a modificare le variabili dei membri privati?
- 4. Quanto sono diverse le semantiche tra Python e JavaScript?
- 5. Compilatori di tipi come funzioni
- 6. Come rendere le funzioni inline in C#
- 7. Quanto sono accurate le unità del mondo reale dei CSS?
- 8. Quanto sono sufficienti le prove?
- 9. Funzioni inline "C" esterne
- 10. Funzioni inline Callgrind
- 11. Quanto sono efficienti le proiezioni di MongoDB?
- 12. Funzioni inline e collegamento esterno
- 13. Può funzioni virtuali essere inline
- 14. Quanto sono stabili le macchine ec2?
- 15. Quanto sono sicure le sessioni PHP?
- 16. Le funzioni JavaScript sono asincrone?
- 17. Come sono definite le direttive __cplusplus in vari compilatori?
- 18. I compilatori C++ possono inline un puntatore a funzione?
- 19. Le funzioni di GCC inline C++ senza la parola chiave 'inline'?
- 20. Variabili locali static/thread_local delle funzioni inline?
- 21. Quanto costose sono le chiamate di funzione in JavaScript?
- 22. le funzioni inline appaiono ancora nel file .prof
- 23. Comprensione del dizionario con funzioni inline
- 24. Quanto sono sicure le funzioni native di php da utilizzare con l'input non filtrato?
- 25. Quanto sono trasferibili le abilità di programmazione tra le lingue?
- 26. Dovrei usare `inline` su funzioni molto usate?
- 27. Content-Disposition: quali sono le differenze tra "inline" e "attachment"?
- 28. Quali sono le differenze tra inline-c e language-c-inline?
- 29. Quanto velocemente sono in pratica le tecniche di Deep Learning (DNN, DBN, ...)?
- 30. Distruzione delle proprietà profonde
Si potrebbe semplicemente testare e guardare l'assemblea! I tuoi documenti del compilatore dovrebbero dirti come specificare la profondità di allineamento; Penso che sia qualcosa come 50 per GCC di default. –
Credo che questo dovrebbe essere specifico del compilatore e non pubblichi alcuna informazione sul tuo compilatore. –
Sotto MSVC si ha il controllo parziale su questo usando '#pragma inline_depth' (http://msdn.microsoft.com/en-us/library/cx053bca.aspx) sebbene abbia avuto problemi con esso in determinate situazioni (come ad esempio ricorsivo inlining, che è pensato per essere possibile, ma non ha mai funzionato, ha finito per farlo manualmente) – Necrolis