0
votes

Méthode en ligne C ++ en montage

permet d'avoir une petite classe appelée myclass em>. J'étais intéressé comment l'apparence de la différence d'origine lorsque la méthode est inlined forte> ou non. J'ai fait deux programmes, avec strong> et sans strong> le mot-clé en ligne em> dans le fichier CPP, mais la sortie .asme était la même. Je sais que le inline em> est juste un indice pour le compilateur et avec la probabilité élevée, j'étais victime d'une optimisation, mais est-il possible de voir la différence sur un petit exemple de RPC d'inlincé et non inlincé Méthode en ASM?

h: p> xxx pré>

cpp: p> xxx pré>

MAIN: P>

    .section    __TEXT,__text,regular,pure_instructions
    .build_version macos, 10, 14
    .globl  _main                   ## -- Begin function main
    .p2align    4, 0x90
_main:                                  ## @main
    .cfi_startproc
## %bb.0:
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register %rbp
    subq    $16, %rsp
    leaq    -8(%rbp), %rdi
    movl    $0, -4(%rbp)
    callq   __ZNK7myClass4getAEv
    xorl    %ecx, %ecx
    movl    %eax, -12(%rbp)         ## 4-byte Spill
    movl    %ecx, %eax
    addq    $16, %rsp
    popq    %rbp
    retq
    .cfi_endproc
                                        ## -- End function

.subsections_via_symbols


6 commentaires

Le compilateur peut ignorer la directive inline et la plupart du temps le fera. La principale raison de l'utilisation de en ligne en C ++ est de spécifier le lien, de ne pas indiquer au compilateur quoi faire.


Vous voulez que l'attribut noinline spécifique à la GCC. Stackoverflow.com/a/1474050/2945027


inline dans le fichier .cpp est toujours faux.


@Sergeya non-sens (votre toujours ). Il existe de nombreuses bonnes raisons pour les fonctions inline D dans le fichier .CPP: Ceux qui ne sont pas exportés (et ne font pas partie d'une interface implémentée dans ce fichier), vivant principalement dans un espace de noms anonyme.


@Walter s'ils sont dans un espace de noms anonyme, ils n'ont pas besoin d'être marqués en ligne car ils ne seront jamais définis qu'une seule fois.


@Walter non-sens, on dirait que vous ne comprenez pas le but de en ligne . Les fonctions non exportées doivent soit être statique ou définie dans l'espace de noms anonyme. En ligne Le mot-clé n'affecte pas le lien, et comme tel, n'empêche pas les fonctions d'être exportées.


4 Réponses :


2
votes

Pour une fonction d'infinle de manière fiable, la définition complète de la fonction doit être disponible dans l'unité de traduction que l'appel apparaît dans.

Depuis la définition de myClass :: getA () n'est pas visible pour main.c , la fonction ne peut pas être inlinée. Il pourrait être inliné dans tous les appels qui sont apparus dans myClass.cpp , mais vous n'en avez pas de ceux-ci.

Pour permettre cette fonction d'être inlinée, vous aurez besoin de déclarez-le comme inline dans le fichier d'en-tête et inclure sa définition, par exemple xxx


3 commentaires

Qu'entendez-vous par «fiable»?


LTO existe, mais est assez floconneux car il ne sait pas quelles annotations le programmeur prévu d'être utilisé en toute sécurité à travers les TU.


Fwiw the inline dans votre exemple est redondant. Les définitions des membres en ligne sont implicitement intégrées.



2
votes

Le mot clé inline a peu à voir avec dire au compilateur aux appels en ligne à la fonction. Quel inline permet à la fonction d'être définie en ligne dans un en-tête.

Utilisation du mot clé inline dans une définition de la fonction permet de définir la fonction dans plusieurs unités de traduction sans violer la règle d'une définition tant que toutes les définitions sont identiques.

Définition d'une fonction en ligne dans un en-tête peut aider le compilateur en ligne appelle à la fonction en permettant la définition complète d'être visible dans plusieurs unités de traduction, mais c'est tout le mot clé inline a à voir avec l'afflexion appels.


0 commentaires

3
votes

Vous n'avez pas donné au compilateur une chance à inline myClass :: getA () (comme expliqué dans une autre réponse). Pour comparer les méthodes Inline Versus hors ligne, comparez l'utilisation de getA () et gettalt () dans le code ci-dessous xxx

Vous pouvez utiliser des optimisations complètes à l'exception de l'optimisation intercédratante (IPO; car cela peut permettre au compilateur d'être même en ligne myClass :: gettalt () ).


0 commentaires

1
votes

gcc -o0 ne permet pas d'activer -Finline-fonction , donc même si les fonctions étaient dans le même fichier, cela n'essaierait pas. Voir aussi Pourquoi cette classe wrapper C ++ Ne pas être inliné? . (Ne vous inquiétez pas d'essayer d'utiliser __ attribut __ ((toujours_inline)) : Vous obtiendrez l'inlinage, les choses ne seront pas optimales.

Vous pouvez obtenir des choses inline avec GCC -O3 -FWHOO-PROGRAM-PROGRAMME * .CPP pour activer l'inlinication des fichiers source. (Indépendamment de ce qu'ils ont été déclarés Inline ou non, c'est juste au compilateur pour décider de ce qui est le mieux).

Le point principal de en ligne est de laisser le compilateur savoir qu'il n'a pas besoin d'émettre une définition autonome d'une fonction si elle choisit de l'aligner sur tous les appelants. (Parce qu'une définition, non seulement une déclaration, cette fonction apparaîtra dans toutes les unités de traduction qui l'utilisent. Donc, si un autre fichier décide de ne pas l'aligner, une définition peut être émise là-bas.)

Les compilateurs modernes utilisent toujours leurs heuristiques normales pour décider si elle vaut la peine d'être inlinité ou non. par exemple. Une grande fonction avec plusieurs appelants ne sera probablement pas inline, pour éviter que le code de code. statique Indique au compilateur qu'aucune autre unité de traduction ne peut voir la fonction, donc s'il n'y a qu'un seul appelant dans ce fichier, il sera très probablement en ligne. (Si vous avez une grande fonction, c'est une mauvaise idée de le faire statique en ligne . Vous obtiendrez une copie de la définition dans chaque fichier dans lequel il n'entrent pas en ligne et l'affranchissement trop agressif. Pour une petite fonction qui va probablement aligner partout, vous devez probablement toujours simplement utiliser inline , pas statique inline , donc au cas où quelque chose prend l'adresse de la fonction là-bas. une définition partagée sur tous les fichiers. inline indique à la liaison de fusionner des définitions en double en double d'une fonction au lieu d'erreurs. Ce comportement est l'une des parties les plus importantes de ce que en ligne , pas l'indice réel du compilateur que vous voulez en ligne.)


gcc -fwhaole-programme (avec tous les fichiers source de la même ligne de commande) donne aux informations suffisantes du compilateur pour effectuer toute ces décision elle-même. Il peut voir si une fonction comporte un seul appelant dans l'ensemble du programme et la configurine au lieu de créer une définition autonome plus argumentation et un appel . .

gcc -flto permet une optimisation du temps de liaison similaire au programme entier, mais ne nécessite pas tous les fichiers .cpp de la ligne de commande à la fois. Au lieu de cela, il stocke le code de gimale dans les fichiers et termine optimisant à l'heure de liaison.


0 commentaires