Benefici di dichiarare una funzione come “in linea”?

Ogni volta che leggo la dichiarazioneinline” in C, si dice che è solo un suggerimento per il compilatore (cioè non deve obbedire). C’è qualche vantaggio nell’aggiungerlo allora, o dovrei semplicemente fare affidamento sul fatto che il compilatore conosca meglio di me?

Ci sono due ragioni per usare la parola chiave inline . Uno è un suggerimento per l’ottimizzazione e puoi tranquillamente ignorarlo; il tuo compilatore è come ignorarlo anche tu. L’altro motivo è di consentire a una funzione di esistere in più unità di traduzione e che l’uso è strettamente necessario. Ad esempio, se inserisci una funzione in un file di intestazione .h, è meglio dichiararla in linea.

I compilatori sono intelligenti, ma possono comunque beneficiare dei suggerimenti dello sviluppatore. Se pensi che alcune delle tue funzioni, in particolare, dovrebbero essere inline, quindi dichiararle come tali. Di certo non fa male.

Generalmente i compilatori moderni renderanno “in linea” le cose che ritengono importanti. Lo lascerei gestire per te.

Modificare:

Dopo aver letto ciò che altri hanno scritto, sai cosa? Penso che lascerei che gestisca la maggior parte del profilo THEN inlining del tuo codice e THEN funzioni inline che sono colli di bottiglia. Il mio consiglio è leggermente colorato da un certo sviluppatore che lavoro a fianco di chi pre-ottimizza tutto il suo codice. La metà del tempo ho bisogno di trascorrere 5 minuti. solo cercando di capire cosa sta cercando di essere realizzato.

Come tutti gli altri hanno detto, la parola chiave è solo un suggerimento, ma è un suggerimento che la maggior parte dei compilatori prende sul serio. Inoltre, la maggior parte dei compilatori sono molto pessimi nell’inlining di funzioni da diverse unità di compilazione – se si definisce Foo() nel file ac , ma lo si chiama in bc , le probabilità sono piuttosto ridotte che incorpori in modo intelligente le chiamate di bc a Foo() . (in effetti, non succederà affatto senza LTCG.) quindi vale la pena utilizzarlo quando si è certi che una funzione debba essere realmente in linea. Questa è una decisione fatta meglio con i tempi empirici.

Ad esempio, sulla mia piattaforma ho misurato la differenza tra una funzione inline e una diretta (non virtuale) di circa 5 nanosecondi, quindi la mia regola empirica è che io funzioni inline che dovrebbero impiegare meno di dieci cicli: accessorie banali e simili. Altre funzioni specifiche vengono successivamente evidenziate quando il mio profiler mi dice che sto sprecando un sacco di tempo nel sovraccarico di chiamarli.

Le domande frequenti sul C ++ hanno buone informazioni su questo. Preferisco usare la funzione inline in quanto fornisce al compilatore maggiori informazioni su cosa mi piacerebbe che facesse. Indipendentemente dal fatto che il compilatore finisca o meno, è sufficiente, ma dargli un piccolo aiuto non guasta.

Non puoi essere assolutamente sicuro che il compilatore catturerà le sezioni “critiche” del tuo codice: usa “in linea” quando sai che è importante.

Un compilatore non è un profiler.

La differenza non è probabile che importi.

Lasciare inline out fino a quando non si misura la performance del codice e si stabilisce che è ansible ottenere alcune prestazioni integrando una funzione specifica che il compilatore ha scelto di trattare normalmente. Anche in questo caso, non c’è alcuna garanzia che il compilatore integrerà quella funzione, ma almeno hai fatto tutto il ansible 🙂

Dato che è solo un suggerimento per il compilatore, il compilatore è libero di ignorarlo, e probabilmente lo farà. Il compilatore ha molte informazioni rilevanti che non hai, come quanta parte di una linea cache occuperà un ciclo e può essere in linea o no caso per caso.

È solo un suggerimento, quindi è improbabile che utilizzarlo danneggi qualsiasi cosa. Quasi certamente dovresti evitare cose specifiche del compilatore che costringano le funzioni ad essere inline o non inline.

La dichiarazione è praticamente inutile e molto diversa dall’intenzione originale. I compilatori hanno preso molta più libertà rispetto a cosa e cosa non in linea (IMO).

È un suggerimento per il compilatore, usarlo ti aiuterà e avrà il significato desiderato solo a volte.

Se è necessario scrivere programmi con prestazioni critiche, non fare affidamento sul compilatore (la conoscenza delle prestazioni e dell’ottimizzazione non viene appresa in un giorno). Di solito c’è un modo per ignorare il giudizio del compilatore (non solo suggerire le preferenze), per forzare l’inlining. Questo è il modo in cui dichiaro una funzione / metodo in linea, più del 95% delle volte (sapendo anche quando è implicito). Se / Quando sai che avresti bisogno di sapere come inline correttamente, quindi impiegare anche la forza-inlining, ma impara quando e come usarlo.

Inlining non è un proiettile d’argento per prestazioni migliori; può avere effetti negativi. L’abuso di inlining può avere alcune conseguenze spaventose in casi estremi, ma in genere le prestazioni sono un po ‘peggiori ei binari sono più grandi se usati in modo improprio. L’uso corretto dell’inlining può avere risultati considerevolmente positivi.

Inlining è anche utile per rimuovere i simboli che altrimenti verrebbero esportati, riducendo il binario, a seconda del numero di istanze e dimensioni.

Un’altra cosa: otterrai diversi collegamenti con C ++.

Fornisce un semplice meccanismo per il compilatore per applicare più OTTIMIZZAZIONI.
Le funzioni inline sono più veloci perché non è necessario spingere e far saltare le cose sullo stack come parametri e l’indirizzo di ritorno; tuttavia, rende il tuo binario leggermente più grande.

Fa una differenza significativa? Per la maggior parte non è abbastanza evidente l’hardware moderno. Ma può fare la differenza, che è abbastanza per alcune persone.

Contrassegnare qualcosa in linea non ti dà la garanzia che sia in linea. È solo un suggerimento per il compilatore. A volte non è ansible, ad esempio quando si ha una funzione virtuale o quando è coinvolta una ricorsione. E a volte il compilatore sceglie di non usarlo. Ho potuto vedere una situazione come questa facendo una differenza rilevabile:

 inline int aplusb_pow2(int a, int b) { return (a + b)*(a + b) ; } for(int a = 0; a < 900000; ++a) for(int b = 0; b < 900000; ++b) aplusb_pow2(a, b);