GoingNative 2013
La conférence de Andrei Alexandrescu lors des GoingNative 2013 est disponible :
Peaufiner son code est important, cela permet d'avoir mieux qu'un simple proof-of-concept, mais quelque chose de performant.
A. Alexandrescu rappelle en insistant fortement que la seule intuition qui ne soit pas fausse au sujet de la performance du code, c'est "je devrais mesurer ça".
Mais la mesure du temps est un problème car elle est gourmande et est assez flou et imprécise. Il recommande d'utiliser des façons détournées de mesurer des performances :
- vitesse du flux (en byte par seconde par exemple)
- saturation du CPU
- consommation d'énergie
- nombre d'instructions exécutées entre chaque résultat
- nombre d'écritures
Organisation des données
Il s'agit selon lui actuellement du problème n°1 pour les performances.
Les premiers 64 bits sont les plus importants car ils sont facilement accessibles par le CPU.
Si vous compressez trop vos données, vous épuiserez vos performances à transformer vos données pour travailler avec.
Les bitfields ne sont pas fait pour être performants mais réduire la taille des données.
Dans les valeurs -1, 0, 1 que l'on vous conseille d'utiliser, votre constante préférée devrait être zéro, car le hardware dispose d'opérations spéciales pour interagir avec lui.
Dévirtualisation
La virtualité en C++ est très efficace pour les grandes hiérarchies, sont flexibles, et les appels virtuels sont optimisés par du load balancing au niveau du cache d'instructions.
Cependant, on paye pour la flexibilité potentielle, non celle réalisé en réalité. De plus, on perd en mémoire car le vptr est toujours au début des structures (donc il occupe les 64 premiers bits qui sont si importants), et on ne peut pas changer le type d'un objet in-situ il faut passer par les constructeurs/destructeurs qui sont relativement couteux. La virtualité est beaucoup moins efficace sur des hiérarchies fermées/petites.
Le switch de type est une possibilité, mais n'est bonne que pour 7 branches maximum, et a l'inconvénient de mélanger le code froid (exécuté rarement) avec le code chaud (exécuté souvent), et le code pour des types différent est obligé d'être concentré en un même point. On échange également la modularité pour des performances.
Implémenter une vtable à la main, bien que donnant un meilleur contrôle des constructeurs/destructeurs et permettant de changer le type in-situ, est bien plus couteux que la vraie.
La solution est une vtable verticale. Bien qu'impliquant beaucoup de casts et ne supportant qu'un nombre statique de classes et de fonctions virtuelles, elles sont bien plus performantes puisqu'elles permettent d'accéder à la bonne fonction en une seule opération.
Pour terminer, après le connaissez vos algorithmes de Sean Parent dans sa conférence qui précède celle-ci, voici le connaissez votre architecture d'Andrei Alexandrescu, cela vous permettra d'écrire un meilleur code.
Élider ou Déplacer, telle est la question.
Par rapport à la construction par copie, la construction par déplacement demande peu de travail. L'élision n'en demande aucun. Or, pas de travail est toujours moins de travail que peu de travail.
Ne faites pas de retour par valeur même si le déplacement est élidé quand cela vous obligera à faire des allocations supplémentaires par ailleurs.
En tous les cas, mesurez .
Conférence précédente : Sean Parent - C++ Seasoning
Évènement : GoingNative 2013
Conférence suivante : Stephan Lavavej - Don't help, the compiler
Et vous,
Qu'en pensez-vous ?