49 votes

Optimisation des constantes et du compilateur en C ++

J'ai lu tous les conseils sur la const-correctness en C++ et qu'il est important (en partie) car il permet au compilateur d'optimiser votre code. Ce que je n'ai jamais vu, c'est une bonne explication sur la façon dont le compilateur utilise ces informations pour optimiser le code, pas même dans les bons livres sur l'explication de ce qui se passe derrière les rideaux.

Par exemple, comment le compilateur d'optimiser une méthode qui est déclarée const vs une qui ne l'est pas mais devrait l'être. Ce qui se passe quand vous introduire des variables mutables? Ils influent sur ces optimisations de const méthodes?

55voto

Luc Touraille Points 29252

Je pense que le mot clé const est principalement introduit pour la compilation de la vérification du programme de sémantique, et non à des fins d'optimisation.

Herb Sutter, dans le GotW #81 article, qui explique très bien pourquoi le compilateur ne peut pas optimiser rien lors du passage de paramètres par référence const, ou lors de la déclaration const valeur de retour. La raison en est que le compilateur n'a aucun moyen d'être sûr que l'objet référencé ne sera pas changé, même si déclarée const : on peut utiliser un const_cast, ou d'un autre code peut avoir un non-const de référence sur le même objet.

Cependant, citer Herb Sutter de l'article :

Il est [seulement] un cas où, en disant: "const" peut vraiment signifier quelque chose, et c'est lorsque les objets sont fabriqués à const le point elles sont définies. Dans ce cas, le compilateur peut souvent réussi à la mettre "vraiment const" les objets dans la mémoire en lecture seule[...].

Il y a beaucoup plus dans cet article, je vous encourage donc le lire: vous aurez une meilleure compréhension de l'optimisation constante par la suite.

35voto

Michael Burr Points 181287

Laissons de côté les méthodes et les examiner seulement les objets const; le compilateur a beaucoup plus de possibilités d'optimisation. Si un objet est déclarée const, puis de l'ISO (ISO/IEC 14882:2003 7.1.5.1(4)):

Sauf que tout membre de la classe déclarée mutable (7.1.1) peut être modifié, tout tentative de modifier un objet const au cours de sa durée de vie (3.8) des résultats de l' un comportement indéfini.

Permet d'ignorer les objets qui peuvent avoir mutable membres - le compilateur est libre de supposer que l'objet ne sera pas modifié, donc il peut produire d'importantes optimisations. Ces optimisations peuvent inclure des choses comme:

  • incorporation de l'objet de valeur directement dans les machines d'instruction opcode
  • l'élimination complète de code qui ne peut jamais être atteint parce que la const objet est utilisé dans une expression conditionnelle qui est connu au moment de la compilation
  • déroulement de la boucle si le const objet est de contrôler le nombre d'itérations d'une boucle

Notez que cela s'applique seulement si l'objet réel est const - il ne s'applique pas aux objets qui sont accessibles par le biais de const pointeurs ou des références parce que les chemins d'accès peuvent conduire à des objets qui ne sont pas const (c'est encore bien défini pour modifier les objets quoique const pointeurs/références tant que l'objet réel est non-const et vous éloigner de la constness de la voie d'accès à l'objet).

Dans la pratique, je ne pense pas qu'il existe des compilateurs qui d'effectuer d'importantes optimisations pour tous les types d'objets const. mais pour les objets qui sont des types primitifs (entiers, caractères, etc.) Je pense que les compilateurs peuvent être assez agressifs dans l'optimisation de l'utilisation de ces éléments.

6voto

Paul Nathan Points 22910

la main commence

Essentiellement, plus les données sont corrigées tôt, plus le compilateur peut se déplacer dans l'affectation réelle des données, assurant ainsi que le pipeline ne reste pas bloqué.

fin de la main

3voto

James Curran Points 55356

Il n'optimise pas la fonction déclarée const.

Il peut optimiser les fonctions qui appellent la fonction déclarée const.

 void someType::somefunc();

void MyFunc()
{
    someType A(4);   // 
    Fling(A.m_val);
    A.someFunc();
    Flong(A.m_val);
}
 

Ici, pour appeler Fling, la valud A.m_val devait être chargée dans un registre de la CPU. Si someFunc () n'est pas const, la valeur devra être rechargée avant d'appeler Flong (). Si someFunc est const, alors nous pouvons appeler Flong avec la valeur qui est toujours dans le registre.

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