2010-06-30 2 views
6

J'ai actuellement des fonctions en ligne appelant une autre fonction inline (une simple fonction 4 lignes getAbs()). Cependant, j'ai découvert en regardant le code assembleur que les "grandes" fonctions en ligne sont bien intégrées, mais le compilateur utilise un saut bl pour appeler la fonction getAbs().en ligne une fonction à l'intérieur d'une autre fonction inline en C

Est-il impossible d'intégrer une fonction dans une autre fonction en ligne? Soit dit en passant, il s'agit d'un code intégré, nous n'utilisons pas les bibliothèques standard. Edit: Le compilateur est WindRiver, et j'ai déjà vérifié que inlining serait bénéfique (4 instructions au lieu de + -40).

+0

Quel compilateur utilisez-vous? Il y a souvent des façons de forcer l'inlining. Je suppose que vous avez déjà profilé votre code et êtes plutôt confiant que l'inline sera bénéfique. Dans GCC, ceci peut être fait avec __attribute __ ((always_inline)). – stinky472

+0

Puis-je vous demander pourquoi vous vous souciez des décisions prises par le compilateur? Avez-vous profilé le code et trouvé le surcoût de cette instruction de saut est en train de tuer la performance? – JeremyP

Répondre

8

Selon le compilateur que vous utilisez, vous pouvez être en mesure d'encourager le compilateur à être moins réticent à l'insertion, par ex. avec gcc vous pouvez utiliser __attribute__ ((always_inline)), avec Intel ICC, vous pouvez utiliser icc -inline-level=1 -inline-forceinline, et avec gcc d'Apple, vous pouvez utiliser gcc -obey-inline.

7

Le mot-clé inline est une suggestion au compilateur, rien de plus. Il est libre de prendre en compte cette suggestion, de l'ignorer complètement ou même de vous mentir et de dire qu'il le fait pendant que ce n'est vraiment pas le cas.

La seule façon de forcer le code à être en ligne est, bien, de l'écrire en ligne. Mais, même, le compilateur peut décider qu'il sait mieux et décider de passer à une autre fonction. Il a beaucoup de latitude dans la génération de code exécutable pour votre source particulière, à condition qu'il ne change pas la sémantique de celui-ci.

Les compilateurs modernes sont plus que capables de générer un meilleur code que la plupart des développeurs ne le feraient dans l'assemblage. Je pense que le mot-clé inline devrait suivre le même chemin que le mot-clé register.

Si vous avez vu la sortie de gcc à son niveau d'optimisation fou, vous comprendrez pourquoi. Il a produit un code que je n'aurais jamais imaginé possible, et cela m'a pris du temps à comprendre.

En outre, vérifiez this pour les optimisations que gcc a réellement, y compris un grand nombre contenant le texte "inline" ou "inline".

+0

Je me risquerais à deviner et dire que le mot-clé a été ajouté lorsque la tâche de déterminer si la fonction pourrait être en ligne était un peu trop grande pour le compilateur (soit en termes de fonctionnalité ou de temps), mais le compilateur est probablement capable de comprendre cela par eux-mêmes, même si le mot-clé inline n'est pas présent. Juste une supposition cependant. –

+0

Je dirais que c'était une estimation assez sûre. Voir ma mise à jour – paxdiablo

+0

Gcc prend-il en charge les optimisations basées sur les profils? Lorsque vous n'utilisez pas ceux-ci, il est logique de suggérer à gcc où inline pourrait vous aider. Ceci est basé sur la connaissance si la fonction sera appelée un * lot * ou non, quelque chose que le compilateur le plus intelligent ne peut toujours pas dire. – Peaker

1

@gramm: Il y a pas mal de scénarios dans lesquels inline n'est pas forcément à votre avantage. La plupart des compilateurs utilisent des heuristiques très avancées pour déterminer quand inline. Lorsque vous discutez de l'inlining, l'idée la plus simple est de faire confiance à votre compilateur pour produire le code le plus rapide.

-1

Je suggère que si votre fonction getAbs() (ressemble à la valeur absolue, mais vous devriez vraiment nous montrer le code avec la question ...) est de 4 lignes, alors vous avez des optimisations beaucoup plus grandes à s'inquiéter que si le code s'incruste ou non.

+0

Soit vous dites que les frais généraux d'appel d'une fonction sont moins importants pour les fonctions courtes, soit vous dites que le fait d'avoir des fonctions courtes est généralement une mauvaise chose, de toute façon vous obtenez -1 –

+0

Non, je dis qu'un une mauvaise implémentation de 'abs()' est un coup de performance beaucoup plus important que le compilateur qui ne parvient pas à l'intégrer. (Et en fait le compilateur peut faire la bonne chose en ne l'insérant pas ..) –

+0

Idem que Pete. Avoir 50 instructions au lieu de 5 est une énorme surcharge, et il devient généralement visible lorsqu'il est utilisé dans une boucle. Je ne suis pas sûr si vous avez l'habitude de travailler avec des microcontrôleurs. – gramm

0

J'ai récemment eu un problème très similaire, lire ce post m'a donné une idée farfelue. Pourquoi ne pas avoir une simple pré-compilation (un simple reg ex devrait faire le travail) analyseur de code qui parseer l'appel de la fonction pour réellement mettre le code source en ligne. utiliser une balise telle que/en ligne// end_of_inline/afin que vous puissiez utiliser les fonctionnalités de ure normales (si vous êtes ou pourriez utiliser un ide. Inclure dans votre processus de construction, de cette façon vous avez l'avantage de la lisibilité et en supprimant l'hypothèse des compilateurs que vous êtes seulement un développeur aussi bon que la plupart et que vous ne comprenez pas quand vous êtes en ligne.Néanmoins, avant d'essayer ceci, vous devriez probablement passer par les options de la ligne de commande du compilateur.

Questions connexes