Profil simple
Dans cette partie, nous allons nous intéresser à un programme qui implémente une simulation physique simple : un gaz d’électrons, protons et neutrons dans une boîte avec des interactions électrostatiques et nucléaires entre ces particules. Le programme est écrit dans un style qui rend hommage aux pratiques modernes de programmation en physique des particules, avec notamment un important recours aux techniques de programmation orientée objet.
Comme les programmes précédents, ce programme prend deux paramètres :
- Un nombre de particules à simuler
- Un nombre de pas de temps à simuler
Si vous ajustez ces paramètres, gardez en tête que la complexité du calcul est quadratique en fonction du nombre de particules puisque chaque particule interagit avec toutes les autres.
Un premier examen de l’exécution via perf stat
suggère que le CPU ne rencontre
pas de difficulté majeure pour exécuter ce programme…
srun --pty \
perf stat -d \
./TPhysics.bin 500 100
…mais comme nous l’avons vu précédemment, ce n’est pas une condition suffisante pour conclure que le programme fait un usage optimal du temps CPU.
Voyons maintenant l’éclairage nouveau apporté sur cette question par
perf report
. Comme avec perf annotate
, on doit d’abord enregistrer des
données avec perf record
, puis visualiser les mesures dans un deuxième temps
avec perf report
:
srun --pty \
perf record \
./TPhysics.bin 500 100 \
&& perf report
Nous nous retrouvons dans une interface console interactive ayant certaines
similarités avec celle de perf annotate
. Après un bref en-tête donnant des
statistiques globales sur la mesure (nombre d’échantillons enregistrés et nombre
approximatif de cycles CPU écoulés) et des titres de colonnes, perf report
affiche une table qui indique, par ordre décroissant de fréquence, les fonctions
qu’exécutait le plus fréquemment le programme lorsque des échantillons ont été
enregistrés.
Pour chaque fonction, perf report
indique…
- Le pourcentage des échantillons où le programme se trouvait dans une fonction
donnée, qui est un estimateur du pourcentage du temps CPU passé à exécuter
chaque fonction.
- Un code couleur est utilisé pour mettre en valeur les fonctions qui semblent contribuer grandement à la consommation de CPU.
- La commande exécutée, information qui peut être utile quand on étudie des
activités multi-processus telles qu’un pipeline
bash
. - Le binaire d’où est issu la fonction exécutée (programme ou bibliothèque).
- Le nom de fonction/symbole ELF, avec un petit indicateur
[.]
qui indique que les fonctions qu’on regarde proviennent de code applicatif. Pour du code noyau, ce serait[k]
.
…et l’on constate donc que notre programme emploie l’essentiel de son temps CPU à exécuter différentes parties de l’allocateur mémoire de la bibliothèque standard C. Il n’est donc pas limité par le calcul flottant, comme on aurait pu le penser naïvement.
On observe aussi une première difficulté liée à l’utilisation de perf report
:
de par son mode de fonctionnement, cet outil marque des nuances entre des points
d’implémentation qui n’ont pas d’importance pour nous. Par exemple, au premier
niveau d’analyse que nous souhaitons avoir ici, la nuance entre _int_free
,
les différentes overloads de operator delete
et operator delete@plt
n’est
pas pertinente, et on voudrait avoir juste une somme des coûts CPU associés à
l’appel de de l’allocateur mémoire. Nous verrons plus loin comment l’obtenir.
Enfin, mentionnons que l’on peut sélectionner l’une des fonctions du programme
avec les flèches haut/bas du clavier et afficher son assembleur annoté dans le
style de perf annotate
avec la touche a
du clavier. Comme dans
perf annotate
, la touche h
permet d’afficher l’aide des commandes clavier
et la touche q
permet de quitter perf report
.
Exercice : Afficher l’assembleur annoté de TParticle::reidInteraction
et
découvrez de quelle nature sont ses instructions CPU les plus chaudes.
Référez-vous à la partie sur perf annotate
si vous avez oublié le mode de fonctionnement de l’assembleur annoté.