12
votes

Le compilateur décidera-t-il quand en ligne mes fonctions (en C ++)?

Je comprends que vous puissiez utiliser le mot-clé en ligne ou simplement mettre une méthode dans une déclaration de classe ALA CORT CORTR ou une méthode de getter, mais le compilateur prend la décision finale sur quand en ligne mes méthodes?

Par exemple:

void Foo::bar() { std::cout << "baz"; }


0 commentaires

9 Réponses :


15
votes

Oui, la décision finale de savoir si vous souhaitez ou non dans votre code dans le compilateur C ++. Le mot-clé en ligne est une suggestion, pas une exigence.

Voici quelques détails sur la manière dont cette décision est traitée dans le compilateur Microsoft C ++


4 commentaires

Pourriez-vous élaborer pourquoi c'est? Je pensais que le point de C ++ est de donner au programmeur suffisamment de corde pour accrocher la Hisself, mais cela semble restrictif. Y a-t-il une bonne raison?


@Hooked, regardez le lien que j'ai posté. Il va dans un peu de détails sur la raison pour laquelle ce n'est pas toujours une bonne chose. Le premier élément qui me vient à l'esprit est la tête de la tête des fonctions récursives.


Le standard indique que même __forceinline ne met pas fin au débat, le compilateur a toujours le mot final. Je peux comprendre lorsque l'inlinisation serait inappropriée, mais si un programmeur / profileur décide de parcourir le compilateur, quelles sont ses options? Ce lien ne détaille pas la raison de laisser le compilateur à décider.


Il peut simplement être impossible de faire connaître une fonction donnée. Cela dit, il convient de noter que certains compilateurs vous donnent toujours le moyen de remplacer la décision finale - par exemple. __ Forceinline en VC ++. Cela ne vous laisse toujours pas vous laisser des fonctions en ligne qui ne peuvent pas éventuellement être inlinées, mais il remplacera le coût / l'analyse des bénéfices du compilateur autrement.



12
votes

si une fionce est inline ou non est, à la fin de la journée, entièrement jusqu'à le compilateur. En règle générale, plus une fonction complexe est en termes de débit, moins le compilateur est probablement de le signaler. et certaines fonctions, telles que des personnes récursives, ne peuvent tout simplement pas être inlinées.

La principale raison de ne pas inliquer une fonction est que cela augmenterait considérablement la taille globale du code, empêchant ainsi l'iot d'être détenu dans le cache du processeur. Cela serait en fait une pessimisation, plutôt qu'une optimisation.

Quant à laisser le programmeur décider de se tirer dans le pied ou d'ailleurs, vous pouvez aligner la fonction vous-même - écrivez le code qui serait entré dans la fonction à ce qui aurait été le site d'appel de la fonction.


8 commentaires

Consultez mon commentaire sur la réponse de Jareedpar, s'il vous plaît.


Les fonctions récursives peuvent être inlinées dans la profondeur spécifiée :)


Comment le compilateur sait-il quelle est la profondeur aura lieu à la compilation?


@Neil Butterworth: Je présume que le compilateur peut voir combien d'itérations il y a si le nombre d'itérations est constant ou une consexpr.


À partir des pages MSDN, il semble que la récursivité en ligne doit augmenter plus de fois que cela peut être nécessaire. Il semble probablement être une pessimation (en termes de taille de code) plus de fois qu'une optimisation (en termes de performance). Oh, AMD BTW, pourriez-vous arrêter de mettre un smiley après chaque commentaire que vous faites ici? Vous en avez même eu une après votre réponse!


@Le_Drow en fait, non, cela ne peut pas. Par exemple, si j'ai un évaluateur d'expression récursif et que je transmettais une corde Cobnst comme une expression, la seule façon du compilateur peut déterminer la profondeur requise consiste à évaluer l'expression. Ceci est une variation du problème d'arrêt.


@Aarak Cela signifie que je ne sais jamais si je devrais prendre vos commentaires au sérieux ou non.


Une fonction pourrait être affinée de manière récursive à une profondeur arbitraire et appelez une version non inline.



1
votes

Selon mes connaissances, le compilateur effectuera automatiquement une fonction que vous avez déclarée inline (ou écriva à l'intérieur d'une déclaration de classe) non-cor ligne s'il trouve une boucle comme pour, etc. C'est un exemple où le compilateur a le dernier mot dans les fonctions en ligne.


3 commentaires

Je ... avez-vous des sources pour sauvegarder cette affirmation?


Une boucle? Pourquoi une boucle? Tu ne veux pas dire récursion?


C'est spécifique de la mise en œuvre. La norme ne dit rien quand une fonction pourrait ne pas être inline; Seule cette mise en œuvre a la décision finale.





2
votes

En tant que question latérale, si j'ai une méthode getter déclarée en dehors de ma classe comme celle-ci: xxx

le compilateur en ligne sous les couvertures?

Cela dépend. Il peut pour tous les appelants dans la même unité de traduction (le fichier .cpp et toutes ses définitions #inclus). Mais il doit encore compiler une version non inline, car il peut y avoir des appelants de cette fonction en dehors de l'unité de traduction. Vous pouvez potentiellement le voir au travail (si votre compilateur peut réellement le faire) à des niveaux d'optimisation élevés. (En particulier: comparez ce qui se passe lorsque vous #incluez tous vos fichiers .cpp en un .cpps par rapport à la mise en page typique. Avec toutes les définitions d'une unité de traduction, les opportunités d'amélioration considérablement.)


2 commentaires

Oh, je ne savais pas cela. Je ne suis pas au courant de ce que fait exactement le lien de lien (j'ai été gâté avec mes IDE de fantaisie, je n'ai jamais eu à compiler par ligne de commande et à traverser le processus).


Comprendre la manière dont la liaison fonctionne doit être assez transparente (vous ne devriez pas avoir besoin de le savoir pour faire du travail). Mais cela finit par être particulièrement important d'en apprendre de manière particulièrement importante en C ++, car tant de constructions de langue ne se comportent pas tout à fait la façon dont vous vous attendez si vous ne savez pas ce qui est visible pour la liaison et ce qui n'est pas. inline est le plus gros, mais la différence entre ce qui se passe dans un .h et .cpp , quel statique signifie que les modèles peuvent aller ... Tout cela vient. Malheureusement, la liaison peut vraiment vous traduire en C ++ si vous ne comprenez pas de manière élémentaire.



4
votes

Comme d'autres personnes ont noté, le mot clé inline est simplement une suggestion au compilateur pour aligner le code. Puisque le compilateur sera systématiquement en ligne de code qui n'a pas été marqué avec inline , et non du code en ligne qui a, le mot clé semble aussi redondant que enregistrement ou (pré-C ++ 0x) auto .

Cependant, il y a une autre chose que le inline Effets de mots-clés: il modifie la linkage de la fonction de externe (la valeur par défaut fonctions) pour inline . La liaison en ligne permet à chaque unité de compilation de contenir sa propre copie du code d'objet et que le linkeur supprimez les copies redondantes de l'exécutable final. Si cela vous rappelle des modèles, oui, les modèles utilisent également une liaison en ligne.


0 commentaires

3
votes

juste pour ajouter mes 5 cents ...

J'ai trouvé ce gourou de la semaine article sur l'inlinisation très utile.

Autant que je me souvienne, j'ai lu quelque part que même un lieur peut faire l'impression, lorsqu'il relie les fichiers d'objet et constate que le code étant lié peut être inlincé.


0 commentaires

1
votes

Si vous êtes vraiment, de manière positive, sans faute, sans faute de ne pas induire le code, il y a toujours la macro. C a soutenu ces années depuis des années et parce qu'ils ne sont que du remplacement du texte avant la compilation, ils sont vraiment, vraiment, tout ce que vous écrivez.

C'est pourquoi le mot-clé «Inline '» (et même dans certains cas, les variantes forcées) peuvent se permettre de ne pas avoir de manière standard de le forcer - vous pouvez toujours simplement écrire une macro.

Cela dit, le mot-clé en ligne est souvent meilleur, car le compilateur sait assez souvent si une fonction en ligne est logique ou non, et comme l'inline peut interagir avec le reste des optimisations du compilateur.


0 commentaires