9
votes

Est-il possible de forcer l'optimisation des appels de la queue sur GCC / Clang?

J'essaie d'écrire un programme dans un style fonctionnel avec C autant que possible. Je connais des compilateurs fins comme GCC / SLIG FAIRE Optimisation de la queue en silence, mais ce n'est pas garanti. Existe-t-il une option pour forcer l'optimisation des appels de queue sur les compilateurs? (Bien sûr, quand il est seulement appelé à la fin de lui-même)


4 commentaires

Le compilateur est probablement plutôt intelligent à cet égard, faites-la confiance. Pas besoin de pas-portable hacks.


Que voulez-vous accéder dans des cas où vous pensez que l'optimisation de la queue devrait se produire, mais le compilateur n'est pas capable de le faire (pour une raison quelconque)?


@Michael Je m'attendais à une erreur de compilation si l'optimisation des appels de queue forcée est impossible à faire.


Vous pouvez forcer GCC à fournir à TCO avec un drapeau de compilateur: -Foptimizizize-sibling-appels (voir draketo.de/light/english/free-software/tco-debug )


7 Réponses :


0
votes

En réalité, beaucoup de compilateurs pour C traitent déjà cela pour vous. Comme étant mentionné, vous pourriez aussi bien laisser le compilateur gérer la plupart de ces choses plutôt que d'essayer de créer des optimisations qui ne fonctionnent pas ailleurs. Souvent, vous trouverez même si vous définissez des drapeaux d'optimisation qu'il n'y a vraiment aucune différence de performance.


1 commentaires

Un moment commun lorsque vous souhaitez forcer l'optimisation des appels de queue est le code fileté. Dans cette situation, une fonction reviendra parfois, mais appelez généralement une autre fonction avec une signature identique (mêmes paramètres, même valeur de retour). Une séquence d'appel de fonction standard exécutera le programme hors de l'espace de pile et une collision presque immédiatement, ce n'est donc pas quelque chose que nous pouvons laisser au compilateur.



5
votes

Clang ne fait aucune optimisation du tout. Il y a un laissez-passer LLVM Tailialim qui peut faire ce que vous voulez (mais cela n'est pas garanti). Vous pouvez l'exécuter séparément avec opt .


2 commentaires

Quel est l'option? Puis-je avoir un lien pour cela?


Sinon, vous pouvez modifier le pilote de clang pour vous assurer qu'il exécute explicitement cette carte.



2
votes

Une réponse méta:

Il existe des leçons qu'il est utile de prendre en charge C à partir de langues fonctionnelles: utilisez de petites fonctions, utilisez des fonctions qui ne mutent pas des globaux ou des arguments d'entrée, ne sont pas effrayés des pointeurs de fonction. Mais il y a une limite à ce que vous pouvez raisonnablement faire ici et à compter sur l'élimination de l'appel de la queue («Appel queue l'optimisation » n'est pas vraiment le bon terme) est probablement au-delà de ce qui est utile. Vous ne pouvez pas forcer le compilateur à utiliser cette stratégie, et même si vous le pouviez, le C résultant serait extrêmement unidiomatique, et difficile à lire pour d'autres, y compris votre avenir futur.

Utilisez des langues vers leurs forces. C est bon pour certaines choses, alors utilisez-le pour ceux-ci, dans un bon style C. Si vous voulez des forces différentes, ou si vous souhaitez utiliser un style fonctionnel (excellente décision!), Utilisez une langue fonctionnelle.


0 commentaires

0
votes

Si c'est vraiment un appel de queue, alors une boucle tandis que la boucle ou un goto ne semblera pas très différent d'un appel récursif. Il suffit de mettre à jour toutes les variables au lieu de les transmettre en tant que paramètres. AFAIK Ceci est la seule voie multi-plateformes en C pour contrôler l'utilisation des piles à tous les niveaux d'optimisation. Il peut également être plus lisible depuis que vous avez une fonction avec une initialisation suivie de la boucle, qui est assez idiomatique. La version récursive de la queue nécessite deux fonctions, une pour l'initialisation et une pour la partie récursive.


1 commentaires

Cela ne vaut que dans des cas triviaux où TCO suit une seule voie à suivre. Les fonctions récursives qui branche de nombreux chemins récursifs sont beaucoup plus propres lorsque cela est représenté avec une récursion.



2
votes

Je ne pense pas que ce soit vraiment applique . Il est automatiquement activé si vous utilisez -O2 , -O3 ou -Os .

En général, je conseillerais contre la réduction de la récursion dans C. Si vous voulez vraiment faire FP, choisissez une langue fonctionnelle. Il y a des cas où il convient, comme QuickSort, BUF si vous prenez une habitude à l'aide de la récursion au lieu de boucles, les chances sont assez élevées que vous soufflez la pile.


0 commentaires

1
votes

Une extension GCC pour Alpha et I386 est décrite dans:

Recursion de la queue appropriée en C (thèse de diplôme) par < un href = "http://www.complang.tuwien.ac.at/schani/" rel = "Nofollow Noreferrer"> Mark Probst , 2001.


0 commentaires

7
votes

Clang 13 "Mustaile" Attribut d'une optimisation de l'appel de la queue dans les fonctions récursives de la queue, même si les optimisations sont désactivées.

https://clang.llvm.org/docs/attribvm.org/docs/attribv p>


0 commentaires