mcpField
H
hardware-counters

hardware-counters

github.com/mohitmishra786开发269556 次安装18 周前更新
代码仓库

关于 hardware-counters

面向性能分析的技能指南,介绍如何用 perf、PAPI 和 Intel PCM 采集及解读硬件性能计数器。适用于需要分析缓存、分支、IPC、内存带宽或定位源代码热点的开发者。

主要功能

  1. 01使用 perf stat 采集 PMU 事件
  2. 02计算 IPC、缓存未命中率和 MPKI
  3. 03查询 CPU 专属原始事件
  4. 04用 perf annotate 关联源代码行
  5. 05通过 PAPI 访问可移植计数器
  6. 06用 Intel PCM 测量内存带宽

适用场景

  1. 01测量程序的缓存未命中率和分支预测失败
  2. 02比较指令数与周期数以计算 IPC
  3. 03定位导致缓存未命中的源代码行
  4. 04分析系统内存带宽

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill hardware-counters

安装后在 Claude Code 中输入/hardware-counters确认已加载。

详细介绍

硬件性能计数器

用途

指导 Agent 分析硬件性能计数器:使用 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. 关键指标和阈值
指标公式良好需关注
IPCinstructions / 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_DCML1 数据缓存未命中
PAPI_L2_TCML2 缓存总未命中数
PAPI_L3_TCML3 缓存总未命中数
PAPI_BR_MSP分支预测错误
PAPI_TLB_DM数据 TLB 未命中
PAPI_FP_INS浮点指令
PAPI_VEC_INS向量/SIMD 指令
7. Intel PCM(性能计数器监视器)
# 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 进行引导式微架构分析
  • 使用 skills/profilers/linux-perf 执行 perf record/report 并生成火焰图
  • 使用 skills/low-level-programming/cpu-cache-opt 应用缓存优化模式
  • 使用 skills/low-level-programming/simd-intrinsics 提升 FLOPS/周期指标

评论

支持 Markdown