hardware-counters について
perf、PAPI、Intel PCMを使ったハードウェア性能カウンター分析のガイドです。キャッシュ、分岐、IPC、メモリ帯域のデータ収集と解釈、ソース行との対応付けを扱います。
主な機能
- 01perf statによるPMUイベント収集
- 02IPC、キャッシュミス率、MPKIの算出
- 03CPU固有のrawイベントの確認
- 04perf annotateによるソース行との対応付け
- 05PAPIによるポータブルなカウンター利用
- 06Intel PCMによるメモリ帯域測定
活用シーン
- 01キャッシュミス率と分岐予測ミスの測定
- 02命令数とサイクル数からのIPC算出
- 03キャッシュミスに関係するソース行の特定
- 04システムのメモリ帯域の分析
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mohitmishra786/ low-level-dev-skills --skill hardware-countersインストール後、Claude Code で/hardware-countersを入力して読み込まれたか確認します。
詳細
ハードウェアパフォーマンスカウンター
目的
ハードウェアパフォーマンスカウンターの分析をエージェントに案内します。perf stat -e による PMU イベントの収集、移植性の高いカウンターアクセスのための PAPI ライブラリの使用、キャッシュミス率と分岐予測ミス率の解釈、IPC の計算、および perf annotate によるイベントとソース行の関連付けを扱います。
トリガー
- 「perf でキャッシュミス率を測定するにはどうすればよいですか?」
- 「分岐予測ミスを数えるにはどうすればよいですか?」
- 「perf で IPC(クロックあたりの命令数)を計算するにはどうすればよいですか?」
- 「ハードウェアカウンターに PAPI ライブラリを使うにはどうすればよいですか?」
- 「どのソース行で最も多くのキャッシュミスが発生しているかを確認するにはどうすればよいですか?」
- 「パフォーマンスカウンターでメモリ帯域幅を測定するにはどうすればよいですか?」
ワークフロー
1. perf stat — 基本的なカウンターの収集
# Basic hardware event summary
perf stat ./prog
# Output:
# Performance counter stats for './prog':
#
# 1,234,567,890 instructions
# 456,789,012 cycles
# 12,345,678 cache-misses # 1.23 % of all cache refs
# 23,456,789 branch-misses # 2.34 % of all branches
#
# 0.456789012 seconds time elapsed
# Derived metrics (computed from the output)
# IPC = instructions / cycles = 1,234,567,890 / 456,789,012 ≈ 2.70
# CPI = cycles / instructions ≈ 0.37
2. -e による PMU イベントの指定
# Specific hardware events
perf stat -e instructions,cycles,cache-misses,branch-misses ./prog
# L1/L2/L3 cache events
perf stat -e \
L1-dcache-loads,L1-dcache-load-misses,\
L2-loads,L2-load-misses,\
LLC-loads,LLC-load-misses \
./prog
# Memory bandwidth (Intel)
perf stat -e \
uncore_imc/cas_count_read/,\
uncore_imc/cas_count_write/ \
./prog
# TLB misses
perf stat -e dTLB-loads,dTLB-load-misses,iTLB-loads,iTLB-load-misses ./prog
# Branch misprediction rate
perf stat -e branches,branch-misses ./prog
# Rate = branch-misses / branches × 100%
# Available events (varies by CPU)
perf list hardware # generic hardware events
perf list cache # cache events
perf list pmu # raw PMU events for your CPU
3. 主なメトリクスとしきい値
| メトリクス | 計算式 | 良好 | 要注意 |
|---|---|---|---|
| IPC | instructions / cycles | > 2.0(最新の x86) | < 1.0 |
| L1 ミス率 | L1-misses / L1-accesses | < 1% | > 5% |
| LLC ミス率 | LLC-misses / LLC-accesses | < 1% | > 10% |
| 分岐ミス率 | branch-misses / branches | < 1% | > 5% |
| MPKI | 1K 命令あたりのミス数 | — | L3 MPKI > 10 = メモリ律速 |
# Compute MPKI (Misses Per Kilo-Instructions)
perf stat -e instructions,LLC-load-misses ./prog
# MPKI = LLC-load-misses / (instructions / 1000)
4. 生の PMU イベント(CPU 固有)
汎用エイリアスにないイベントには、生のイベントコードを使用します。
# Intel: use perf list or look up in Intel SDM
# Format: rXXYY where XX=umask, YY=event code
perf stat -e r0124 ./prog # example Intel raw event
# List Intel events with ocperf (OpenCL Perf Events)
pip install ocperf
ocperf.py list | grep "mem_load"
# Use libpfm4 for event names
pfm_ls | grep "MEM_LOAD"
perf stat -e $(pfm_ls | grep "MEM_LOAD_RETIRED.L3_MISS") ./prog
# AMD: similar approach
perf stat -e r04041 ./prog # AMD raw event
5. perf record/annotate によるソースレベルの注釈
# Record with hardware events
perf record -e LLC-load-misses -g ./prog
# Annotate: show source lines sorted by cache miss count
perf annotate --stdio
# Interactive (requires debug symbols)
perf report
# Press 'a' on a function to annotate it
# Combined: record hotspot + annotate
perf record -e cycles:u -g ./prog
perf annotate --symbol=my_function --stdio 2>/dev/null | head -40
# Example annotate output:
# Percent | Source code
# 45.23 | for (int i = 0; i < N; i++)
# 3.12 | sum += data[i]; ← cache miss here (strided access)
6. PAPI — ハードウェアカウンター用の移植可能な API
PAPI は、異なる CPU アーキテクチャ間で使用できる移植性の高い C API を提供します。
#include <papi.h>
#include <stdio.h>
int main(void) {
int Events[] = {PAPI_TOT_INS, PAPI_TOT_CYC,
PAPI_L2_TCM, PAPI_BR_MSP};
long long values[4];
if (PAPI_library_init(PAPI_VER_CURRENT) != PAPI_VER_CURRENT) {
fprintf(stderr, "PAPI init failed\n");
return 1;
}
PAPI_start_counters(Events, 4);
// --- Code to measure ---
do_work();
// -----------------------
PAPI_stop_counters(values, 4);
printf("Instructions: %lld\n", values[0]);
printf("Cycles: %lld\n", values[1]);
printf("IPC: %.2f\n", (double)values[0]/values[1]);
printf("L2 cache misses: %lld\n", values[2]);
printf("Branch mispred: %lld\n", values[3]);
return 0;
}
# Build with PAPI
gcc -O2 -g -o prog prog.c -lpapi
# Available PAPI events on your system
papi_avail -a | head -30
papi_native_avail | grep "L3" # native events with "L3"
一般的な PAPI プリセット:
| プリセット | イベント |
|---|---|
PAPI_TOT_INS | 命令の総数 |
PAPI_TOT_CYC | サイクルの総数 |
PAPI_L1_DCM | L1 データキャッシュミス |
PAPI_L2_TCM | L2 キャッシュミスの総数 |
PAPI_L3_TCM | L3 キャッシュミスの総数 |
PAPI_BR_MSP | 分岐予測ミス |
PAPI_TLB_DM | データ TLB ミス |
PAPI_FP_INS | 浮動小数点命令 |
PAPI_VEC_INS | ベクトル/SIMD 命令 |
7. Intel PCM(Performance Counter Monitor)
# Intel PCM — system-wide counters, no root required on modern kernels
git clone https://github.com/intel/pcm
cd pcm && cmake -S . -B build && cmake --build build
# Measure memory bandwidth
./build/bin/pcm-memory 1 # sample every 1 second
# Core utilization + IPC
./build/bin/pcm 1
# Cache miss breakdown per socket
./build/bin/pcm 1 -csv | head -20
関連スキル
- マイクロアーキテクチャ分析のガイドには
skills/profilers/intel-vtune-amd-uprofを使用します - perf record/report とフレームグラフの生成には
skills/profilers/linux-perfを使用します - キャッシュ最適化パターンの適用には
skills/low-level-programming/cpu-cache-optを使用します - FLOPS/サイクルのメトリクス改善には
skills/low-level-programming/simd-intrinsicsを使用します
コメント
Markdown 対応