Aller au contenu

pahole - Analyse de Disposition de Struct et de Ligne de Cache

pahole - Analyse de Disposition de Struct et de Ligne de Cache

pahole (« poke-a-hole ») lit les informations de débogage DWARF ou BTF et imprime la disposition réelle en mémoire des structures C — où chaque champ s’assoit, combien de remplissage le compilateur a inséré, et combien de lignes de cache la struct traversent. Les compilateurs remplissent les structs pour satisfaire l’alignement, et une struct négligemment ordonnée peut gaspiller des dizaines d’octets et traverser des lignes de cache supplémentaires. Sur les structures de données chaudes, cela se traduit directement par des ratés de cache. pahole rend le gaspillage visible pour que vous puissiez réordonner les champs et le réduire.

Installation

PlateformeCommande
Debian/Ubuntusudo apt install dwarves
Fedora/RHELsudo dnf install dwarves
Arch Linuxsudo pacman -S pahole
De sourceconstruire le projet dwarves
Vérifierpahole --version

Votre binaire doit être construit avec les infos de débogage (-g). Les binaires dépouillés n’ont rien pour pahole à lire.

Utilisation de Base

CommandeDescription
pahole ./myprogramAfficher toutes les structs du binaire
pahole -C mystruct ./myprogramUne struct spécifique
pahole -C task_struct /sys/kernel/btf/vmlinuxStruct du noyau via BTF
pahole --sizes ./myprogramLister les tailles de struct
pahole -H 1 ./myprogramUniquement les structs avec ≥1 trou

Lecture de la Sortie

struct example {
        char                       flag;                 /*     0     1 */

        /* XXX 7 bytes hole, try to pack */

        long int                   counter;              /*     8     8 */
        char                       name[16];             /*    16    16 */
        int                        id;                   /*    32     4 */

        /* XXX 4 bytes hole, try to pack */

        void *                     ptr;                  /*    40     8 */

        /* size: 48, cachelines: 1, members: 5 */
        /* sum members: 37, holes: 2, sum holes: 11 */
};
AnnotationSignification
/* offset size */Décalage d’octet et taille de chaque champ
XXX N bytes holeRemplissage que le compilateur a inséré
size:Taille totale de la struct
cachelines:Combien de lignes de 64 octets elle traverse
sum holes:Total d’octets gaspillés
last cacheline:Octets utilisés dans la ligne finale

Trouver le Gaspillage Partout dans une Base de Code

CommandeTrouve
pahole -H 1 ./binStructs avec trous
pahole --nr_members ./binTriées par nombre de membres
pahole -c 2 ./binStructs traversant ≥2 lignes de cache
pahole -E ./binDévelopper les structs imbriquées en ligne
pahole -a ./binAfficher les détails d’alignement/packing
# Quelles structs gaspillent le plus de mémoire à cause du remplissage ?
pahole -H 8 ./myprogram | head -50

Fixing Layout

Le correctif standard est ordonnement des champs de l’alignement le plus grand au plus petit :

/* Avant : 48 octets, 11 gaspillés */
struct bad  { char flag; long counter; char name[16]; int id; void *ptr; };

/* Après : 40 octets, 0 gaspillé */
struct good { long counter; void *ptr; char name[16]; int id; char flag; };
TechniqueEffet
Ordonnancer par alignement décroissantÉlimine la plupart des trous
Grouper les champs chaudsLes garder dans une ligne de cache
Diviser les champs froids dans une deuxième structLes données chaudes restent denses
__attribute__((packed))Supprime le remplissage — mais peut ralentir l’accès non aligné
BitfieldsEmpaqueter les petits drapeaux

pahole peut même suggérer une réorganisation avec --reorganize :

pahole --reorganize -C mystruct ./myprogram

Travail du Noyau (BTF)

CommandeObjectif
pahole -C task_struct /sys/kernel/btf/vmlinuxInspecter une struct du noyau actif
pahole -J vmlinuxGénérer BTF à partir de DWARF
pahole --btf_encodeCodage BTF pour les outils eBPF

La génération de BTF est la raison pour laquelle dwarves est une dépendance de construction du noyau — CO-RE d’eBPF en dépend.

Quand Cela Compte

SituationImpact
Des millions d’instances d’une structLes économies de mémoire évoluent linéairement
Boucle chaude touchant les champs structMoins de lignes = moins de ratés
Sérialisation réseau/disqueStructs plus petites, moins d’E/S
Mémoire embarquée/contrainteChaque octet compte
Une struct utilisée deux foisNe pas se déranger

pahole vs Outils Associés

OutilRéponses
paholeComment cette struct est-elle disposée, et où est le gaspillage ?
perfEst-ce que j’ai réellement des ratés de cache ?
valgrind (cachegrind)Comportement simulé du cache
heaptrackOù la mémoire du heap va-t-elle ?

Utilisez perf pour confirmer que les ratés de cache sont votre goulot d’étranglement, puis pahole pour corriger la disposition qui les cause.

Ressources