Tracepoints
A la fin de la partie sur perf list
, nous avons évoqué comment perf stat
nous permettait d’aller au-delà des appels système et de compter divers
événements internes au noyau Linux, via des tracepoints (points de code
instrumentés) que nous pouvons énumérer avec perf list tracepoint
.
Avec perf trace
, nous avons accès à des informations supplémentaires sur ces
tracepoints :
- Nous pouvons observer le déroulé temporel des passages à ces endroits du noyau
- Nous pouvons y connaître certaines informations choisies par l’auteur du tracepoint
Considérons, par exemple, la commande dd
suivante, qui écrit quelques
kilo-octets de données aléatoires dans un fichier du disque dur SATA du serveur
d’une façon fabuleusement inefficace :
dd if=/dev/urandom of=/hdd/${USER}/randomness.bin bs=42 count=123 oflag=sync
En examinant les appels système qu’elle fait, on n’apprendrait pas grand-chose :
srun --pty \
perf trace -s \
dd if=/dev/urandom of=/hdd/${USER}/randomness.bin bs=42 count=123 oflag=sync
En revanche, on peut en apprendre davantage en étudiant l’activité des tracepoints associés à différentes parties du noyau Linux impliquées dans l’écriture de données sur le disque :
- Le système de fichier utilisé sur
/hdd
(ext4, comme vous le diramount
) - Le périphérique bloc sous-jacent (
/dev/sda1
pour les intimes) - Le cache disque qui s’intercale grosso modo entre les deux
Utiliser perf stat
avec ces tracepoints nous permet déjà de formuler
quelques hypothèses :
srun --pty \
perf stat -e 'block:*,ext4:*,writeback:*' \
dd if=/dev/urandom of=/hdd/${USER}/randomness.bin bs=42 count=123 oflag=sync
Sortie de perf stat
On constate ainsi que certaines parties du noyau semblent traversées une fois par bloc, d’autres plusieurs fois par bloc (le nombre de fois où elles sont traversées est approximativement multiple du nombre de blocs), et d’autres plus rarement, ce qui suggère qu’elle sont appelées une fois tous les quelques blocs ou bien durant les phases d’initialisation et de finalisation du programme.
Et, bien sûr, on voit aussi que certaines parties du noyau ne sont pas traversées, ce qui peut dans certain cas être une information tout aussi importante.
Mais le niveau de détail accessible via perf trace
n’est tout simplement pas
comparable :
srun --pty \
perf trace -e 'block:*,ext4:*,writeback:*' \
dd if=/dev/urandom of=/hdd/${USER}/randomness.bin bs=42 count=123 oflag=sync
Sortie de perf trace
Avec ce nouvel outil, on commence vraiment à voir assez précisément qu’est-ce que fait le noyau Linux des requêtes d’écriture disque qu’on lui envoie, quelles parties du noyau sont sollicitées, quels ordres sont envoyés au matériel sous-jacent… et ce niveau de détail peut faire la différence quand on essaie de démêler pourquoi une application relativement complexe est loin d’atteindre les performances d’E/S théoriquement permises par le périphérique de stockage qu’elle utilise.
Exercice : Répétez cette analyse en remplaçant oflag=sync
par
conv=fsync
, puis en supprimant carrément cette option. Qu’est-ce que ça
change au niveau de l’activité noyau ?