web-dev-qa-db-fra.com

Les foncteurs sont-ils réellement plus rapides que les pointeurs vers les fonctions?

Selon Scott Meyers, un domaine où C++ brille sur C est que les objets fonction sont plus rapides que les pointeurs de fonction. Il dit que c'est parce que les objets fonction sont alignés, ce qui augmente la vitesse.

J'ai deux questions à ce sujet:

  1. Comment pouvons-nous vérifier que les objets fonction sont en fait alignés? Pouvons-nous vérifier cela dans la pratique?

  2. L'incrustation des objets fonction dépend-elle du compilateur que nous utilisons ou tous les compilateurs se comportent-ils comme ceci?

58
user7140484

Les normes C++ et C laissent une grande liberté aux compilateurs. Les compilateurs sont libres de compter jusqu'à 1 milliard entre chaque instruction, ou ne le font que si un entier a une valeur première.

Les "vrais" compilateurs décents ne le font pas. Il s'agit d'un problème de qualité de mise en œuvre.

Intégration d'objets de fonction dans quelque chose comme std::sort est quelque chose que tout vrai compilateur fait. Il est extrêmement facile de détecter ce qui doit être inséré dans ces cas, car les informations de type contiennent le code qui doit être inséré.

Le faire avec un pointeur de fonction est plus difficile. Le faire avec un pointeur de fonction où tout a été converti en void* ou char* les pointeurs est encore plus difficile.

Cela a pour effet qu'en pratique, un appel de style C à qsort contre un appel de style C++ à std::sort peut entraîner un gros avantage pour std::sort.

qsort est environ 2 fois plus lent que std::sort, comme indiqué ici , dans une situation ridiculement simple de tri d'entiers disposés de façon aléatoire.

L'inspection de la sortie réelle du code d'assemblage est principalement un détail, et cela demande beaucoup de travail pour peu de retour. Prendre des exemples concrets du monde réel vous donne une idée de l'ampleur réelle de l'impact.

Tous les 3 de clang, gcc et MSVC étaient capables de faire std::sort être nettement plus rapide que leur qsort. Et comme il s'agit d'une optimisation facile, alors que l'optimisation des pointeurs de fonction en appels en ligne ne l'est pas, vous vous attendez à ce que moins de compilateurs majeurs ne soient pas meilleurs que cela à qsort.

76
  1. Comment vérifier que les objets de fonction sont bien en ligne? Pouvons-nous vérifier cela dans la pratique?

Bien sûr, inspectez le code assembleur finalement émis.

  1. Les objets fonction inline dépendent du compilateur que nous utilisons, ou tous les compilateurs se comportent comme ça?

Cela dépend fortement de l'implémentation du compilateur et du niveau d'optimisation utilisé.
Donc non, il n'y a aucune garantie que certains compilateurs (linkers) se comportent ainsi.

Les appels via les pointeurs de fonction ne peuvent cependant pas être alignés.


Selon lui, les objets de fonction sont alignés, il y a donc une augmentation de la vitesse.

IMO "les objets de fonction sont alignés" devraient être mieux lus (ou entendus, je ne sais pas d'où vient cette citation):

objets de fonction peut être inséré tandis que les appels via les pointeurs de fonction ne le peuvent pas.

18

Oui, les objets fonction peuvent conduire à un code plus rapide. Mais la seule façon de garantir cela est de se comparer.

  1. documentation dit: " GCC peut toujours être incapable d'inline une fonction pour de nombreuses raisons; le -Winline L'option peut être utilisée pour déterminer si une fonction n'a pas été insérée et pourquoi pas. "

  2. Bien sûr, cela dépendra du compilateur, de la version, des indicateurs, etc. Parfois, l'inline peut être contre-productif (surcharge de code, etc.), donc chaque compilateur a son propre ensemble de règles pour décider si une fonction doit être insérée. Soit dit en passant, le mot clé inline n'est qu'un indice, et certaines bibliothèques telles que eigen ont du mal à appliquer l'inline.

1
YvesgereY