pahole - 構造体レイアウト & キャッシュラインの分析 チートシート
pahole(「穴をつつく」)はDWARFまたはBTFデバッグ情報を読み込み、C構造体の実際のメモリー レイアウトを出力します—各フィールドの座置、コンパイラーが挿入したパディングの量、構造体がスパンするキャッシュ ラインの数。コンパイラーはアライメントを満たすために構造体をパディング済みにし、不用心に順序付けられた構造体は数十バイトを無駄にし、追加のキャッシュ ラインをまたげます。ホット データ構造でこれは直接キャッシュ ミスに変換されます。paholeは無駄を見えるようにし、フィールドを再順序付けして縮小することができます。
インストール
| Platform | Command |
|---|
| Debian/Ubuntu | sudo apt install dwarves |
| Fedora/RHEL | sudo dnf install dwarves |
| Arch Linux | sudo pacman -S pahole |
| From source | dwarvesプロジェクトをビルド |
| Verify | pahole --version |
バイナリーはデバッグ情報でビルドする必要があります(-g)。剥き出しのバイナリーはpaholeが読み取るものはありません。
基本的な使用法
| Command | Description |
|---|
pahole ./myprogram | バイナリー内のすべての構造体を表示 |
pahole -C mystruct ./myprogram | 1つの特定の構造体 |
pahole -C task_struct /sys/kernel/btf/vmlinux | BTF経由のカーネル構造体 |
pahole --sizes ./myprogram | 構造体サイズをリスト |
pahole -H 1 ./myprogram | ≥1ホール持つ構造体のみ |
出力の読み取り
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 */
};
| Annotation | Meaning |
|---|
/* offset size */ | 各フィールドのバイト オフセットとサイズ |
XXX N bytes hole | コンパイラーが挿入したパディング |
size: | 合計構造体サイズ |
cachelines: | スパンするキャッシュ ラインの数 |
sum holes: | 総浪費バイト |
last cacheline: | 最後のラインで使用されたバイト |
コードベース全体の無駄を検索
| Command | Finds |
|---|
pahole -H 1 ./bin | ホール付き構造体 |
pahole --nr_members ./bin | メンバー数でソート済み |
pahole -c 2 ./bin | ≥2キャッシュ ラインをスパンする構造体 |
pahole -E ./bin | ネストされた構造体をインライン展開 |
pahole -a ./bin | アライメント/パッキング詳細を表示 |
# どの構造体はパディングに最も多くメモリーを浪費するか?
pahole -H 8 ./myprogram | head -50
レイアウトの修正
標準フィックスはフィールドを最大から最小のアライメント順に順序付けするです:
/* Before: 48 bytes, 11 wasted */
struct bad { char flag; long counter; char name[16]; int id; void *ptr; };
/* After: 40 bytes, 0 wasted */
struct good { long counter; void *ptr; char name[16]; int id; char flag; };
| Technique | Effect |
|---|
| Order by descending alignment | ほとんどのホール除去 |
| Group hot fields together | ホット データは1つのキャッシュ ラインに保つ |
| Split cold fields into a second struct | ホット データは密に保つ |
__attribute__((packed)) | パディング削除—ただしアラインされていないアクセスが遅い可能性があります |
| Bitfields | 小さいフラグをパック |
paholeは--reorganizeで再順序付けを提案さえできます:
pahole --reorganize -C mystruct ./myprogram
カーネル作業(BTF)
| Command | Purpose |
|---|
pahole -C task_struct /sys/kernel/btf/vmlinux | ライブ カーネル構造体を検査 |
pahole -J vmlinux | DWARFからBTFを生成 |
pahole --btf_encode | eBPFツーリング用BTFエンコーディング |
BTF生成はdwarvesがカーネル ビルド依存関係である理由です—eBPFのCO-REはそれに依存します。
これが重要な場合
| Situation | Impact |
|---|
| Millions of instances of a struct | メモリー節約リニア スケール |
| Hot loop touching struct fields | キャッシュ ラインが少ない = ミス少ない |
| Network/disk serialization | 小さい構造体、I/O少ない |
| Embedded/constrained memory | すべてのバイト数える |
| A struct used twice | 気に留めないでください |
pahole対関連ツール
| Tool | Answers |
|---|
| pahole | この構造体はどのようにレイアウトされており、無駄はどこ? |
| perf | 実際にキャッシュ ミスしている? |
| valgrind (cachegrind) | シミュレートされたキャッシュ動作 |
| heaptrack | ヒープ メモリーはどこに移動? |
perfを使用してキャッシュ ミスがボトルネックであることを確認し、それからpaholeを使用してレイアウトを修正します。
リソース