23 votes

Les mots-clés d'optimisation en C et C++ sont-ils raisonnables?

Nous avons tous entendu la ligne "ne pas utiliser register", en expliquant que essayer de surpasser un compilateur est une erreur.

register, d'après ce que je sais, ne concerne pas spécifiquement les registres du CPU, mais plutôt le fait qu'une variable donnée ne peut pas être référencée de manière indirecte. Je suppose que c'est souvent considéré comme obsolète car les compilateurs peuvent détecter automatiquement un manque d'adressage, rendant ces optimisations transparentes.

Mais si nous sommes fermes sur cet argument, ne peut-on pas appliquer la même logique à chaque mot-clé axé sur l'optimisation en C? Pourquoi utilisons-nous par exemple inline et restrict de C99?

Je suppose que certaines choses comme l'aliasing rendent la déduction de certaines optimisations difficiles ou même impossibles, alors où doit-on tracer la ligne avant de commencer à entrer dans le territoire du Compilateur Suffisamment Intelligent?

Où devrait-on tracer la ligne en C et C++ entre fournir des informations d'optimisation au compilateur et supposer qu'il sait ce qu'il fait?

ÉDIT: Jens Gustedt a souligné que ma confusion entre C et C++ n'est pas correcte puisque deux des mots-clés ont des différences sémantiques et l'un d'eux n'existe pas en C++ standard. J'avais un bon lien sur register en C++ que j'ajouterai si je le trouve...

9voto

NPE Points 169956

Je conviendrais que register et inline sont quelque peu similaires à cet égard. Si le compilateur peut voir le corps de l'appelé lors de la compilation d'un site d'appel, il devrait être en mesure de prendre une bonne décision sur l'inlining. L'utilisation du mot-clé inline à la fois en C et en C++ a plus à voir avec les mécaniques de rendre le corps de la fonction visible qu'avec autre chose.

restrict, en revanche, est différent. Lors de la compilation d'une fonction, le compilateur n'a aucune idée de quels seront les sites d'appel. Pouvoir supposer qu'il n'y a pas d'aliasing peut permettre des optimisations qui seraient autrement impossibles.

5voto

CashCow Points 18388

inline est utilisé dans le scénario où vous implémentez une fonction non modélisée dans l'en-tête puis l'incluez à partir de plusieurs unités de compilation.

Cela garantit que le compilateur ne crée qu'une seule instance de la fonction comme s'il était inliné, de sorte que vous n'obtenez pas d'erreur de liaison pour le symbole défini plusieurs fois. Cependant, cela n'oblige pas le compilateur à l'inliner réellement.

Il existe des drapeaux GNU je pense force-inline ou similaire mais c'est une extension de langage.

5voto

James Kanze Points 96599

register ne dit même pas que vous ne pouvez pas référencer la variable indirectement (du moins en C++). Il l'a dit dans le C original, mais cela a été abandonné.

Savoir si essayer de surpasser le compilateur est une erreur de débutant dépend de l'optimisation. Pas beaucoup de compilateurs, par exemple, vont convertir sin(x) * sin(x) + cos(x) * cos(x) en 1.

Aujourd'hui, la plupart des compilateurs ignorent register, et personne ne l'utilise, car les compilateurs sont devenus suffisamment performants en allocation de registres pour faire un meilleur travail que vous avec register. En fait, respecter register rendrait généralement le code généré plus lent. Ce n'est pas le cas pour inline ou restrict : dans les deux cas, il existe des techniques, au moins théoriquement, qui pourraient permettre au compilateur de faire un meilleur travail que vous. Ces techniques ne sont cependant pas répandues, et (autant que je sache, du moins), ont un très grand surcoût de temps de compilation, avec dans certains cas des temps de compilation qui augmentent exponentiellement avec la taille du programme (ce qui les rend plus ou moins inutilisables sur la plupart des programmes réels - des temps de compilation mesurés en années ne sont vraiment pas acceptables).

En ce qui concerne la ligne à tracer... cela change avec le temps. Quand j'ai commencé à programmer en C, register faisait une différence significative et était largement utilisé. Aujourd'hui, non. J'imagine qu'avec le temps, la même chose pourrait se produire avec inline ou restrict - certains compilateurs expérimentaux sont très proches avec inline déjà.

5voto

Gordon Milne Points 51

Ceci est une question piège mais je vais plonger quand même.

Les compilateurs sont beaucoup mieux pour optimiser que votre programmeur moyen. Il fut un temps où je programmais sur un 68030 de 25 MHz et j'ai eu un certain avantage de l'utilisation du register car l'optimiseur du compilateur était si mauvais. Mais c'était en 1990.

Je considère inline tout aussi mauvais que register.

En général, mesurez d'abord avant de modifier. Si vous constatez que votre code fonctionne si mal que vous voulez utiliser register ou inline, prenez une grande respiration, reculez et cherchez d'abord un meilleur algorithme.

Récemment (c'est-à-dire au cours des 5 dernières années), j'ai passé en revue des bases de code et supprimé des fonctions inline en abondance sans aucun changement perceptible dans les performances. La taille du code, cependant, bénéficie toujours de la suppression des méthodes inline. Ce n'est pas un gros problème pour votre monstre multicœur de style x86 standard de l'ère moderne, mais cela compte si vous travaillez dans l'espace embarqué.

2voto

Eric Postpischil Points 36641

C'est une cible mouvante, car la technologie des compilateurs s'améliore. (Eh bien, parfois elle change plus qu'elle n'améliore, mais cela a le même effet de rendre vos tentatives d'optimisation vaines, ou pire.)

En général, vous ne devriez pas deviner si un mot-clé d'optimisation ou une autre technique d'optimisation est bonne ou non. Il faut apprendre beaucoup sur le fonctionnement des ordinateurs, y compris la plate-forme particulière que vous ciblez, et sur le fonctionnement des compilateurs.

Par conséquent, une règle concernant l'utilisation de diverses techniques d'optimisation est de se demander si je sais que le compilateur ne fera pas le meilleur travail ici? Suis-je prêt à m'engager pour un certain temps, le compilateur restera-t-il stable lorsque ce code est utilisé, suis-je prêt à réécrire le code lorsque le compilateur change cette situation? En général, il faut être un ingénieur logiciel expérimenté et compétent pour savoir quand vous pouvez faire mieux que le compilateur. Il est également utile si vous pouvez parler aux développeurs du compilateur.

Cela signifie que les gens ne peuvent pas vous donner une réponse ici qui soit une directive définitive. Cela dépend du compilateur que vous utilisez, de votre projet, de vos ressources, de vos objectifs, etc.

Bien que certaines personnes disent de ne pas essayer de surpasser le compilateur en matière d'optimisation, il y a différents domaines de l'ingénierie logicielle où les gens font mieux que le compilateur et où il vaut la peine de payer des gens pour cela.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X