性能指标(Performance Metrics)

收集各种性能事件在性能分析中非常有帮助。然而,这里有一个注意点。假设你运行了一个程序并收集了 MEM_LOAD_RETIRED.L3_MISS 事件(用于统计 LLC 未命中次数),结果显示为十亿次。这听起来确实很多,于是你决定调查这些缓存未命中来自哪里。等等!你确定这是一个问题吗?如果程序只执行了二十亿次加载,那么确实是个问题,因为一半的加载都在 LLC 中未命中。但相反,如果程序执行了一万亿次加载,那么每一千次加载中只有一次导致 L3 缓存未命中。

这就是为什么除了硬件性能事件之外,性能工程师(performance engineer)还经常使用指标(metrics)——这些指标是在原始事件基础上构建的。表 perf_metrics 展示了 Intel 第 12 代 Golden Cove 架构的指标列表,以及描述和公式。该列表并不详尽,但展示了最重要的指标。Intel CPU 完整指标列表及其公式可以在 TMA_metrics.xlsx 中找到。1 [PerfMetricsCaseStudy] 展示了如何在实践中使用性能指标。

指标名称 描述 公式
L1MPKI 每千条指令的 L1 缓存真实未命中次数(针对已退休的按需加载)。 1000 * MEM_LOAD_RETIRED.L1_MISS_PS / INST_RETIRED.ANY
L2MPKI 每千条指令的 L2 缓存真实未命中次数(针对已退休的按需加载)。 1000 * MEM_LOAD_RETIRED.L2_MISS_PS / INST_RETIRED.ANY
L3MPKI 每千条指令的 L3 缓存真实未命中次数(针对已退休的按需加载)。 1000 * MEM_LOAD_RETIRED.L3_MISS_PS / INST_RETIRED.ANY
Branch Mispr. Ratio 所有分支中预测错误的比率 BR_MISP_RETIRED.ALL_BRANCHES / BR_INST_RETIRED.ALL_BRANCHES
Code STLB MPKI 每千条指令的 STLB(第二级 TLB)推测性代码未命中次数(完成页表遍历的任意页大小未命中) 1000 * ITLB_MISSES.WALK_COMPLETED / INST_RETIRED.ANY
Load STLB MPKI 每千条指令的 STLB 数据加载推测性未命中次数 1000 * DTLB_LD_MISSES.WALK_COMPLETED / INST_RETIRED.ANY
Store STLB MPKI 每千条指令的 STLB 数据存储推测性未命中次数 1000 * DTLB_ST_MISSES.WALK_COMPLETED / INST_RETIRED.ANY
Load Miss Real Latency L1 D-cache 未命中按需加载操作的平均延迟(以核心周期计) L1D_PEND_MISS.PENDING / MEM_LD_COMPLETED.L1_MISS_ANY
ILP 每核心的指令级并行度(有执行时平均执行的 μops 数量) UOPS_EXECUTED.THREAD / UOPS_EXECUTED.CORE_CYCLES_GE1, 若启用 SMT 则除以 2
MLP 每线程的内存级并行度(至少有一个 L1 未命中按需加载时的平均未命中数量) L1D_PEND_MISS.PENDING / L1D_PEND_MISS.PENDING_CYCLES
DRAM BW Use GB/sec 读写操作的平均外部内存带宽使用量(GB/s) ( 64 * ( UNC_M_CAS_COUNT.RD + UNC_M_CAS_COUNT.WR ) / 1GB ) / Time
IpCall 每次近调用(near call)的指令数(数字越小表示发生率越高) INST_RETIRED.ANY / BR_INST_RETIRED.NEAR_CALL
Ip Branch 每个分支的指令数 INST_RETIRED.ANY / BR_INST_RETIRED.ALL_BRANCHES
IpLoad 每次加载的指令数 INST_RETIRED.ANY / MEM_INST_RETIRED.ALL_LOADS_PS
IpStore 每次存储的指令数 INST_RETIRED.ANY / MEM_INST_RETIRED.ALL_STORES_PS
IpMispredict 每次非推测性分支预测错误的指令数 INST_RETIRED.ANY / BR_MISP_RETIRED.ALL_BRANCHES
IpFLOP 每次 FP(浮点)操作的指令数 参见 TMA_metrics.xlsx
IpArith 每次 FP 算术指令的指令数 参见 TMA_metrics.xlsx
IpArith Scalar SP 每次 FP 算术标量单精度指令的指令数 INST_RETIRED.ANY / FP_ARITH_INST.SCALAR_SINGLE
IpArith Scalar DP 每次 FP 算术标量双精度指令的指令数 INST_RETIRED.ANY / FP_ARITH_INST.SCALAR_DOUBLE
Ip Arith AVX128 每次算术 AVX/SSE 128 位指令的指令数 INST_RETIRED.ANY / ( FP_ARITH_INST.128B_PACKED_DOUBLE+ FP_ARITH_INST.128B_PACKED_SINGLE)
Ip Arith AVX256 每次算术 AVX* 256 位指令的指令数 INST_RETIRED.ANY / ( FP_ARITH_INST.256B_PACKED_DOUBLE+ FP_ARITH_INST.256B_PACKED_SINGLE)
Ip SWPF 每次软件预取指令(任意类型)的指令数 INST_RETIRED.ANY / SW_PREFETCH_ACCESS.T0:u0xF

表:Intel Golden Cove 架构的性能指标列表(不完整)及其描述和公式。

关于这些指标,有几点说明。首先,ILP 和 MLP 指标并不代表应用程序的理论最大值;它们衡量的是应用程序在特定机器上的实际 ILP 和 MLP。在拥有无限资源的理想机器上,这些数字会更高。其次,除"DRAM BW Use"和"Load Miss Real Latency"之外的所有指标都是分数;我们可以对每个指标进行相当直接的推理,判断某个指标是高还是低。但要理解"DRAM BW Use"和"Load Miss Real Latency"指标,我们需要结合上下文。对于前者,我们想知道程序是否使内存带宽饱和。后者给出了缓存未命中平均代价的概念,单独来看意义不大,除非你了解缓存层次结构中每个组件的延迟。我们将在下一节讨论如何确定缓存延迟和峰值内存带宽。

一些工具可以自动报告性能指标。如果工具没有这个功能,你始终可以手动计算这些指标,因为你知道公式和必须收集的相应性能事件。表 perf_metrics 提供了 Intel Golden Cove 架构的公式,但只要底层性能事件可用,你就可以在其他平台上构建类似的指标。

1. TMA 指标 - https://github.com/intel/perfmon/blob/main/TMA_Metrics.xlsx

results matching ""

    No results matching ""