Méthodes de profilage

La mesure exacte du temps passé par des évènements se produisant pendant l'exécution d'une région de code (par exemple, une fonction) nécessite que soit effectué un ajout de code de mesure avant et après cette région. Ce code lit le temps ou bien un compteur global d'évènement, et calcule les différences. Le code original doit ainsi être changé avant l'exécution. C'est ce que l'on appelle l'instrumentation. L'instrumentation peut être faite par le programmeur lui-même, le compilateur, ou bien par le système d'exécution. Comme les régions intéressantes sont généralement imbriquées, la surcharge due à la mesure influence toujours la mesure elle-même. Ainsi, l'instrumentation doit être effectuée sélectivement et les résultats doivent être interprétés avec précaution. Bien sûr, ceci fait que l'analyse des performances se basant sur la mesure exacte est un processus très complexe.

La mesure exacte est possible grâce à des compteurs matériels (ce qui inclut des compteurs s'incrémentant sur un tic de temps) fournis dans les processeurs modernes et qui sont incrémentés quand un évènement se produit. Comme nous voulons attribuer des évènements à des régions de code, sans utiliser de compteurs, nous devons gérer chaque évènement en incrémentant un compteur pour la région de code courante nous-mêmes. Faire ceci au niveau logiciel n'est bien sûr pas possible. Toutefois, si on part de l'hypothèse que la distribution des évènements sur le code source est identique quand on regarde à chaque énième évènement, au lieu de chaque évènement, nous avons construit une méthode de mesure réglable par rapport à la surcharge induite. C'est ce que l'on appelle l'échantillonnage. L'échantillonnage à base de temps (NdT : Time Based Sampling ou TBS) utilise un temporisateur pour regarder régulièrement le compteur de programme, afin de créer un histogramme sur le code du programme. L'échantillonnage à base d'évènements (NdT : Event Based Sampling ou EBS) se sert des compteurs matériels des processeurs modernes et utilise un mode dans lequel le gestionnaire d'interruptions est appelé sur les valeurs basses du compteur, en générant un histogramme de la distribution d'évènements correspondante. Dans le gestionnaire, le compteur d'évènement est toujours réinitialisé au  n de la méthode d'échantillonnage. L'avantage de l'échantillonnage est que le code n'a pas besoin d'être modifié, mais ceci reste un compromis : la supposition d'au-dessus est correcte si n est petit, mais plus n est petit, plus la surcharge du gestionnaire d'interruptions est importante.

Il existe une autre méthode de mesure qui est de simuler ce qui arrive au niveau de l'ordinateur quand on exécute un code donné, c'est-à-dire une simulation contrôlée de code. La simulation est toujours dépendante du modèle de la machine qui est plus ou moins précis. Cependant, pour des modèles très détaillés de machine, s'approchant de la réalité, le temps de simulation peut être assez inacceptable pour une utilisation courante. L'avantage est que l'on peut insérer dans un code donné un code de mesure / simulation aussi complexe qu'il soit sans perturber les résultats. Faire ceci directement avant l'exécution (ce que l'on appelle instrumentation dynamique), en utilisant le binaire original, est très confortable pour l'utilisateur : aucune recompilation n'est nécessaire. Cette méthode devient utilisable quand on ne simule que quelques parties de la machine avec un modèle simple. En outre, les résultats produits par des modèles simples sont souvent plus faciles à comprendre : le problème fréquent avec le vrai matériel est que les résultats incluent des effets de chevauchement de différentes parties de la machine.