perf iostat
Toutes les commandes perf
que nous avons étudiées jusqu’à présent ont pour
fonction d’étudier le comportement du CPU ou du code qui s’y exécute. Mais
perf iostat
, elle, étudie le volume des échanges entre le CPU et les
périphériques (stockage, GPU, réseau…) via le bus PCI-express (PCIe).
C’est donc par exemple un outil approprié pour savoir si une interconnexion CPU-périphérique est saturée, pour peu que l’on sache quel est le débit crète attendu (ex : PCIe 3.0 x16 = 16 Go/s).
Tout d’abord, on peut obtenir une liste des ports PCIe racine que perf iostat
peut interroger :
perf iostat list
Pour savoir quels périphériques sont raccordés à ces ports, on peut utiliser la
commande /sbin/lspci -D
. Le résultat contiendra un grand nombre de
“périphériques” qui sont en réalité des composants internes du CPU, voici un
affichage simplifié qui ne les inclut pas pour plus de clarté :
/sbin/lspci -D | grep -v 'Intel Corporation Sky Lake-E'
L’adressage PCIe est construit de telle sorte que le numéro de bus (la 1ère paire de chiffres hexadécimaux dans l’adresse) d’un enfant est compris entre celui du port racine auquel il est raccordé et celui du port racine suivant, donc…
- La carte graphique est raccordée au port racine 0000:20.
- Le SSD système est raccordé au port racine 0000:2c.
- Les autres périphériques (USB, SATA, réseau, audio…) sont raccordés au port racine 0000:00.
- Le port racine 0000:14 n’est connecté qu’à des ressources internes au CPU.
Pour illustrer cela, commençons par écrire 1 Gio de zéros sur le SSD par blocs de 4 Mio en surveillant l’ensemble des ports PCIe racine :
srun --pty --exclusive \
perf iostat \
dd if=/dev/zero of=~/.Private/test.dump \
bs=4M count=256 oflag=direct \
; rm ~/.Private/test.dump
On voit dans le rapport produit par perf iostat
qu’aucun des ports PCIe racine
n’a été sollicité de façon significative à l’exception de celui connecté au SSD.
Sur celui-ci, 1026 Mio de données ont été lus par le SSD depuis la RAM (ces données ayant été préalablement préparées par le CPU). On observe donc un petit surcroît de trafic lié au protocole de communication CPU-SSD, mais qui reste très modeste ici.
On voit aussi que les transferts de données utilisent la technique du DMA (Direct Memory Access), où c’est le périphérique de stockage qui fait l’essentiel du travail pour transférer les données. C’est le cas général sur un système moderne.
Pour ce qui concerne le débit, dans le cas présent, l’utilitaire dd
le calcule
pour nous. Mais un intérêt de perf iostat
est que cet utilitaire est
utilisable même sur des programmes qui ne sont pas instrumentés pour mesurer
leur volume de données, en divisant le volume de données transféré par la durée
de la mesure.
On voit en tout cas que le débit est de 2 Go/s, ce qui pourrait saturer
l’interconnexion sur certaines carte mères (ports PCIe 3.0 x2), mais pas toutes
(certaines ont des ports x4). Il faudrait donc avoir les spécifications de la
carte mère et du SSD pour conclure, mais celles-ci n’ont malheureusement pas été
fournies par HP pour srv-calcul-ambulant
.
En revanche, si on fait la même expérience avec le disque dur…
srun --pty --exclusive \
perf iostat \
dd if=/dev/zero of=hdd/$USER/test.dump \
bs=4M count=256 oflag=direct \
; rm /hdd/$USER/test.dump
…on voit qu’on est très loin d’atteindre le débit minimal d’un port PCIe pour la génération 3.0, qui est de 1 Go/s (canal 1x). On peut donc conclure sans spécifications supplémentaires que c’est le disque dur qui limite les performances d’écriture ici, et pas l’interconnexion.
Mentionnons pour conclure que sur des systèmes où il y a beaucoup de ports PCIe
racine (c’est le cas des système en rack, surtout quand ils sont multi-CPU), il
peut être intéressant de n’en surveiller et n’en afficher que quelques uns.
C’est possible de le faire en passant les numéros de port racine à perf iostat
,
avant la commande à surveiller, sous forme de liste séparée par des virgules
(ex : perf iostat 0000:2c,0000:20 <commande>
).
Exercice : En vous inspirant des commandes dd ci-dessus, créez une charge de
travail qui copie 1 Gio de données du SSD au disque dur et surveillez-la avec
perf iostat
en restreignant l’affichage aux ports PCIe auxquels le SSD et le
disque dur sont connectés. Pour plus de réalisme, vous pouvez générer des
données aléatoires en utilisant /dev/random comme source plutôt que /dev/zero.