Outils de profilage

Le plus connu des outils de profilage est l'outil de la suite GCC, gprof : on doit compiler le programme avec l'option -pg ; le lancement du programme génère un fichier gmon.out, que l'utilisateur peut lire avec gprof. L'inconvénient principal de cette méthode est l'obligation de passer par une recompilation pour préparer l'exécutable, qui doit être lié de façon statique. La méthode utilisée ici est l'instrumentation générée par le compilateur. Celle-ci mesure les arcs d'appels se produisant dans les fonctions et en accord avec des compteurs d'appels, en conjonction avec un TBS, qui donne un histogramme de distribution du temps sur le code. En utilisant les deux informations, il est possible de calculer de manière heuristique le temps d'inclusion des fonctions, c'est-à-dire le temps passé dans une fonction ainsi que toutes les fonctions qu'elle a appelées.

Pour une mesure exacte des évènements, il existe des librairies avec des fonctions capables de lire les compteurs de performance matériels. Les plus connus sont le patch PerfCtr pour Linux® et les librairies indépendantes de l'architecture PAPI et PCL. Comme toujours, une mesure exacte nécessite une instrumentation du code, comme indiqué au-dessus. D'autres utilisent les librairies elles-mêmes ou utilisent des systèmes d'instrumentation automatiques comme ADAPTOR (pour l'instrumentation de sources FORTRAN), ou encore DynaProf (injection de code par DynInst).

OProfile est un outil de profilage au niveau système pour Linux® utilisant l'échantillonnage.

Dans beaucoup d'aspects, une manière agréable de profiler est d'utiliser Cachegrind ou Callgrind, qui sont des simulateurs utilisant l'environnement d'instrumentation d'exécution Valgrind. Comme il n'y a pas besoin d'accéder aux compteurs hardware (souvent difficile avec les installations Linux® actuelles), et comme les binaires devant être profilés n'ont pas besoin d'être modifiés, ceci est une bonne alternative à d'autres outils de profilage. L'inconvénient du ralentissement dû à la simulation peut être réduit en n'effectuant la simulation que sur les parties intéressantes du programme, et peut-être seulement sur quelques itérations d'une boucle. Sans instrumentation de la mesure/simulation, l'usage de Valgrind ne provoque qu'un ralentissement d'un facteur de 3 à 5. Et si on n'est intéressé que par l'arbre d'appels et le nombre d'appels, le simulateur du cache peut être désactivé.

La simulation du cache est la première étape dans l'approximation des temps réels. En effet, sur les systèmes modernes, l'exécution est très sensible à l'exploitation de ce qu'on appelle des caches (zones de mémoire petites et rapides, et qui permettent d'accélérer les accès répétés aux mêmes emplacements mémoire). Cachegrind fait cette simulation du cache en interceptant les accès mémoires. Les données produites incluent le nombre d'accès sur la mémoire des instructions / des données, les échecs des caches de niveau L1 / L2, et elle met en relation les lignes du code source avec les fonctions du programme exécuté. En combinant ces compteurs d'échecs et en utilisant des temps de latence de processeurs connus, on peut faire une estimation du temps passé.

Callgrind est une extension de Cachegrind qui construit l'arbre d'appels d'un programme à la volée, c'est-à-dire comment les fonctions s'appellent entre elles et combien d'évènements se produisent lors de l'exécution d'une fonction. De plus, les données de profilage devant être collectées peuvent être divisées en threads ou en contextes de chaînes d'appels. Il peut aussi fournir des données de profilage au niveau instruction afin de permettre l'annotation d'un code désassemblé.