pahole - Struct Layout & Cache-Line Analysis Cheatsheet
pahole (“poke-a-hole”) liest DWARF- oder BTF-Debug-Informationen und druckt das tatsächliche Speicherlayout von C-Strukturen — wo jedes Feld sitzt, wie viel Padding der Compiler eingefügt hat und wie viele Cache-Zeilen die Struktur umfasst. Compiler polstern Strukturen aus, um die Ausrichtung zu erfüllen, und eine sorglos geordnete Struktur kann Dutzende von Bytes verschwenden und zusätzliche Cache-Zeilen überqueren. Bei heißen Datenstrukturen bedeutet das direkt Cache-Misses. pahole macht die Verschwendung sichtbar, damit Sie Felder neu ordnen und schrumpfen können.
Installation
| Plattform | Befehl |
|---|
| Debian/Ubuntu | sudo apt install dwarves |
| Fedora/RHEL | sudo dnf install dwarves |
| Arch Linux | sudo pacman -S pahole |
| Aus Quelle | Baue das dwarves-Projekt |
| Überprüfung | pahole --version |
Deine Binärdatei muss mit Debug-Info gebaut werden (-g). Gestrippte Binärdateien haben nichts für pahole zum Lesen.
Grundlegende Verwendung
| Befehl | Beschreibung |
|---|
pahole ./myprogram | Zeige alle Strukturen in der Binärdatei |
pahole -C mystruct ./myprogram | Eine spezifische Struktur |
pahole -C task_struct /sys/kernel/btf/vmlinux | Kernel-Struktur via BTF |
pahole --sizes ./myprogram | Liste Struktur-Größen auf |
pahole -H 1 ./myprogram | Nur Strukturen mit ≥1 Loch |
Ausgabe lesen
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 */
};
| Anmerkung | Bedeutung |
|---|
/* offset size */ | Byte-Offset und Größe jedes Feldes |
XXX N bytes hole | Padding, das der Compiler eingefügt hat |
size: | Gesamtstruktur-Größe |
cachelines: | Wie viele 64-Byte-Zeilen es umfasst |
sum holes: | Insgesamt vergeudete Bytes |
last cacheline: | In der letzten Zeile verwendete Bytes |
Vergeudung über ein Codebase-hinweg finden
| Befehl | Findet |
|---|
pahole -H 1 ./bin | Strukturen mit Löchern |
pahole --nr_members ./bin | Sortiert nach Mitgliederzahl |
pahole -c 2 ./bin | Strukturen, die ≥2 Cache-Zeilen umfassen |
pahole -E ./bin | Verschachtelte Strukturen inline erweitern |
pahole -a ./bin | Zeige Ausrichtungs-/Packungsdetails |
# Welche Strukturen verschwenden die meisten Speicher durch Padding?
pahole -H 8 ./myprogram | head -50
Layout beheben
Der Standard-Fix ist Felder von größter zu kleinster Ausrichtung ordnen:
/* Vor: 48 Bytes, 11 verschwendet */
struct bad { char flag; long counter; char name[16]; int id; void *ptr; };
/* Nach: 40 Bytes, 0 verschwendet */
struct good { long counter; void *ptr; char name[16]; int id; char flag; };
| Technik | Effekt |
|---|
| Ordne nach fallender Ausrichtung | Beseitigt die meisten Löcher |
| Gruppiere heiße Felder zusammen | Halte sie in einer Cache-Zeile |
| Teile kalte Felder in eine zweite Struktur | Heiße Daten bleiben dicht |
__attribute__((packed)) | Entfernt Padding — aber verlangsamt möglicherweise unausgerichteten Zugriff |
| Bitfields | Packe kleine Flags |
pahole kann sogar eine Neuordnung mit --reorganize vorschlagen:
pahole --reorganize -C mystruct ./myprogram
Kernel-Arbeit (BTF)
| Befehl | Zweck |
|---|
pahole -C task_struct /sys/kernel/btf/vmlinux | Inspiziere eine Live-Kernel-Struktur |
pahole -J vmlinux | Generiere BTF aus DWARF |
pahole --btf_encode | BTF-Kodierung für eBPF-Tools |
BTF-Generierung ist der Grund, warum dwarves eine Kernel-Build-Abhängigkeit ist — eBPFs CO-RE vertraut darauf.
Wenn das wichtig ist
| Situation | Auswirkung |
|---|
| Millionen Instanzen einer Struktur | Speicher-Einsparungen skalieren linear |
| Heiße Schleife, die Struktur-Felder berührt | Weniger Cache-Zeilen = weniger Misses |
| Netzwerk-/Disk-Serialisierung | Kleinere Strukturen, weniger I/O |
| Eingebetteter/eingeschränkter Speicher | Jedes Byte zählt |
| Eine Struktur verwendet zweimal | Kümmere dich nicht |
| Tool | Antwortet |
|---|
| pahole | Wie ist diese Struktur angeordnet, und wo ist die Verschwendung? |
| perf | Cache-Miss ich tatsächlich? |
| valgrind (cachegrind) | Simuliertes Cache-Verhalten |
| heaptrack | Wohin geht der Heap-Speicher? |
Verwende perf um zu bestätigen, dass Cache-Misses dein Bottleneck sind, dann pahole, um das Layout zu beheben.
Ressourcen