Je sais que inline est un indice ou une demande au compilateur et qu'il est utilisé pour éviter les frais généraux d'appel de fonction.
Alors sur quelle base peut-on déterminer si une fonction est candidate ou non à l'inlining? Dans quel cas faut-il éviter l'inlining?
inline
est au nouveau venu C ++ ce queCFLAGS
sont au nouveau venu Gentoo: non, compiler avec-O3 -funroll-loops -finline-functions
ne fera pas voler votre ancien Pentium;)Réponses:
Éviter le coût d'un appel de fonction n'est que la moitié de l'histoire.
faire:
inline
au lieu de#define
inline
: un code plus rapide et des exécutables plus petits (plus de chances de rester dans le cache de code)ne pas:
lors du développement d'une bibliothèque, afin de rendre une classe extensible à l'avenir, vous devez:
Rappelez-vous que le
inline
mot-clé est une indication pour le compilateur: le compilateur peut décider de ne pas insérer une fonction et il peut décider d'insérer des fonctions qui n'ont pas été marquéesinline
en premier lieu. J'évite généralement la fonction de marquageinline
(à part peut-être lors de l'écriture de très très petites fonctions).Concernant les performances, l'approche judicieuse est (comme toujours) de profiler l'application, puis éventuellement
inline
un ensemble de fonctions représentant un goulot d'étranglement.Références:
EDIT: Bjarne Stroustrup, le langage de programmation C ++:
EDIT2: ISO-IEC 14882-1998, 7.1.2 Spécificateurs de fonction
la source
inline
est bien plus qu'un indice pour le compilateur. Il modifie les règles linguistiques sur plusieurs définitions. De plus, avoir des données statiques n'est pas une raison pour éviter d'incruster une fonction. L'implémentation est obligée d'allouer un seul objet statique pour chaque fonction statique que la fonction soit déclaréeinline
ou non. Les classes sont toujours extensibles si elles ont des constructeurs en ligne et des destructeurs virtuels. Et le destructeur d'accolades vides est la seule fonction virtuelle qu'il est parfois judicieux de laisser en ligne.inline
, le résultat est que la fonction n'est pas incorporée: vous payez le prix de l'appel et chaque unité de traduction qui inclut et appelle la fonction obtient sa propre copie du code et des variables statiques. La raison de ne pas intégrer les constructeurs et les destructeurs lors du développement d'une bibliothèque est la compatibilité binaire avec les futures versions de votre bibliothèqueinline
fonctions peuvent être intégrées si le compilateur en a envie. Et lesinline
fonctions ne seront pas intégrées si le compilateur décide de ne pas les intégrer. Comme l'a dit Charles Bailey, cela change les règles linguistiques. Plutôt que de le considérer comme un indice d'optimisation, il est plus juste de le considérer comme un concept complètement différent. Leinline
mot-clé indique au compilateur d'autoriser plusieurs définitions, et rien d'autre. L'optimisation "inlining" peut être appliquée à presque toutes les fonctions, qu'elles soient marquées ou noninline
.inline
pour obtenir l'inlining de fonction. Parfois, nous voulons les autres avantages, comme contourner l'ODR.inline
a très peu à voir avec l'optimisation.inline
est une instruction au compilateur de ne pas produire d'erreur si la définition de fonction donnée se produit plusieurs fois dans le programme et une promesse que la définition se produira dans chaque traduction utilisée et partout où elle apparaîtra, elle aura exactement la même définition.Compte tenu des règles ci-dessus,
inline
convient aux fonctions courtes dont le corps ne nécessite pas d'inclure des dépendances supplémentaires sur ce dont une simple déclaration aurait besoin. Chaque fois que la définition est rencontrée, elle doit être analysée et le code de son corps peut être généré, ce qui implique une surcharge du compilateur sur une fonction définie une seule fois dans un seul fichier source.Un compilateur peut en ligne (c'est-à-dire remplacer un appel à la fonction par du code qui effectue cette action de cette fonction) tout appel de fonction qu'il choisit. Auparavant, il ne pouvait "évidemment" pas intégrer une fonction qui n'était pas déclarée dans la même unité de traduction que l'appel, mais avec l'utilisation croissante de l'optimisation du temps de liaison, même ce n'est plus vrai maintenant. Il est également vrai que les fonctions marquées
inline
peuvent ne pas être insérées.la source
inline
mot-clé? Et qu'est-ce qu'une heureuse coïncidence?Dire au compilateur d'incorporer une fonction est une optimisation, et la règle la plus importante de l'optimisation est que l'optimisation prématurée est la racine de tout mal. Écrivez toujours du code clair (en utilisant des algorithmes efficaces), puis profilez votre programme et n'optimisez que les fonctions qui prennent trop de temps.
Si vous trouvez qu'une fonction particulière est très courte et simple, et qu'elle est appelée des dizaines de milliers de fois dans une boucle interne étroite, cela pourrait être un bon candidat.
Vous pourriez être surpris, cependant - de nombreux compilateurs C ++ intégreront automatiquement de petites fonctions pour vous - et ils pourraient également ignorer votre demande d'inline.
la source
/FAcs
dans Visual Studio,-s
dans GCC) pour voir exactement ce qu'il fait. D'après mon expérience, ces deux compilateurs pèsent assez lourdement sur le mot-clé en ligne.inline
mot-clé. Autrement dit, si vous voyez la fonction en cours d'inclusion et que vous en supprimez leinline
spécificateur, elle sera toujours incorporée. Si vous avez des exemples spécifiques du contraire, partagez-les!inline
mot clé empêche-t-il le "code clair"? Le mot clé "optimisation prématurée" est prématuré et non optimisation. Dire que vous devriez activement * éviter les optimisations n'est que de la bêtise. Le but de cette citation est que vous devez éviter les optimisations qui peuvent ne pas être nécessaires et avoir des effets secondaires néfastes sur le code (comme le rendre moins maintenable). Je ne vois pas comment leinline
mot-clé va rendre le code moins maintenable, ou comment il peut être dangereux de l'ajouter à une fonction.La meilleure façon de le savoir est de profiler votre programme et de marquer les petites fonctions qui sont appelées de nombreuses fois et de graver les cycles du processeur comme
inline
. Le mot clé ici est "petit" - une fois que la surcharge de l'appel de fonction est négligeable par rapport au temps passé dans la fonction, il est inutile de les intégrer.L'autre utilisation que je suggérerais est que si vous avez de petites fonctions qui sont appelées suffisamment souvent dans le code critique pour que le cache soit pertinent, vous devriez probablement les intégrer également. Encore une fois, c'est quelque chose que le profileur devrait être en mesure de vous dire.
la source
L'optimisation prématurée est la racine de tout Mal!
En règle générale, je n'inline généralement que des "getters" et des "setters". Une fois que le code fonctionne et est stable, le profilage peut montrer quelles fonctions pourraient bénéficier de l'inlining.
D'un autre côté, la plupart des compilateurs modernes ont d'assez bons algorithmes d'optimisation et incorporeront ce que vous auriez dû incorporer pour vous.
Reasuming - écrivez des fonctions en ligne sur une seule ligne et vous inquiétez des autres plus tard.
la source
Les fonctions en ligne peuvent améliorer les performances de votre code en éliminant le besoin de pousser des arguments dans la pile. si la fonction en question est dans une partie critique de votre code, vous devez prendre la décision inline not inline dans la partie optimisation de votre projet,
vous pouvez en savoir plus sur les inlines dans la FAQ c ++
la source
J'utilise souvent des fonctions en ligne non pas comme une optimisation mais pour rendre le code plus lisible. Parfois, le code lui-même est plus court et plus facile à comprendre que les commentaires, les noms descriptifs, etc. Par exemple:
Le lecteur connaît immédiatement la sémantique complète du code.
la source
Je suis généralement une règle empirique où je crée une fonction avec 3-4 instructions simples en ligne. Mais il est bon de se rappeler qu'il ne s'agit que d'un indice pour le compilateur. L'appel final pour le rendre en ligne ou non est pris par le compilateur uniquement. S'il y a plus que ces nombreuses déclarations, je ne déclarerai pas en ligne, car avec un compilateur stupide, cela peut conduire à un gonflement du code.
la source
Le meilleur moyen serait d'examiner et de comparer les instructions générées pour les instructions en ligne et non en ligne. Cependant, il est toujours prudent d'omettre
inline
. L'utilisationinline
peut entraîner des problèmes dont vous ne voulez pas.la source
Lorsque je décide d'utiliser ou non en ligne, je garde généralement l'idée suivante à l'esprit: sur les machines modernes, la latence de la mémoire peut être un goulot d'étranglement plus important que les calculs bruts. On sait que les fonctions incorporées souvent appelées augmentent la taille de l'exécutable. En outre, une telle fonction pourrait être stockée dans le cache de code du CPU, ce qui diminuera le nombre de défauts de cache lorsque ce code doit être accédé.
Par conséquent, vous devez décider vous-même: est-ce que l'inlining augmente ou diminue la taille du code machine généré? Quelle est la probabilité que l'appel de la fonction entraîne un échec du cache? Si cela est répandu dans tout le code, je dirais que la probabilité est élevée. S'il est limité à une seule boucle serrée, la probabilité est, espérons-le, faible.
J'utilise généralement l'inlining dans les cas que j'énumère ci-dessous. Cependant, lorsque vous êtes réellement préoccupé par les performances, le profilage est essentiel. De plus, vous voudrez peut-être vérifier si le compilateur prend réellement l'indication.
la source
En outre, une méthode en ligne a des effets secondaires graves lors de la maintenance de grands projets. Lorsque le code en ligne est modifié, tous les fichiers qui l'utilisent seront reconstruits automatiquement par le compilateur (c'est un bon compilateur). Cela pourrait vous faire perdre beaucoup de temps de développement.
Lorsqu'une
inline
méthode est transférée dans un fichier source et n'est plus en ligne, l'ensemble du projet doit être reconstruit (du moins c'est mon expérience). Et aussi lorsque les méthodes sont converties en inline.la source
inline
ou non n'a pas d'importance (sauf sans leinline
mot - clé, vous obtiendrez des erreurs de l'éditeur de liens - mais leinline
mot-clé n'est pas le problème causant des reconstructions excessives.On ne devrait utiliser le qualificatif de fonction en ligne que lorsque le code de fonction est petit. Si les fonctions sont plus grandes, vous devriez préférer les fonctions normales car l'économie d'espace mémoire vaut le sacrifice relativement petit en vitesse d'exécution.
la source
Lorsque vous pensez que votre code est suffisamment petit pour être utilisé en ligne et que vous vous souvenez de la fonction en ligne, dupliquez votre code et collez-le là où la fonction est appelée, cela peut être suffisant pour augmenter votre temps d'exécution, mais aussi augmenter votre consommation de mémoire. Vous ne pouvez pas utiliser la fonction en ligne lorsque vous utilisez une fonction boucle / variable statique / récursive / commutateur / goto / virtuelle. Virtuel signifie attendre l'exécution et les moyens en ligne pendant la compilation afin qu'ils ne puissent pas être utilisés simultanément.
la source
J'ai lu quelques réponses et je constate qu'il manque des choses.
La règle que j'utilise est de ne pas utiliser en ligne, sauf si je veux qu'elle soit en ligne. Ça a l'air idiot, maintenant l'explication.
Les compilateurs sont assez intelligents et les fonctions courtes font toujours en ligne. Et ne fait jamais fonctionner long en ligne, à moins que le programmeur ne dise de le faire.
En fait,
inline
c'est une commande pour le compilateur, il n'a pas de choix et après leinline
mot clé rend tout le code en ligne. Ainsi, vous ne pouvez jamais utiliser deinline
mot-clé et le compilateur concevra le code le plus court.Alors quand l'utiliser
inline
?À utiliser si vous souhaitez avoir du code en ligne. Je ne connais qu'un seul exemple, car je ne l'utilise que dans une seule situation. C'est l'authentification de l'utilisateur.
Par exemple, j'ai cette fonction:
Quelle que soit la taille de cette fonction, je veux l'avoir en ligne car cela rend mon logiciel plus difficile à déchiffrer.
la source