Neoverse N2作为Armv9架构的服务器级处理器核心,其性能监控单元(PMU)的设计体现了现代多核处理器的复杂内存层次结构。与消费级CPU不同,N2的PMU事件需要放在CHI协议和CMN互连架构的背景下理解。
CMN(Coherent Mesh Network)是N2处理器的关键创新,它通过AMBA CHI协议实现多核一致性。在实际测试中,单个CMN-700实例可以连接多达128个N2核心,形成NUMA架构。这种设计带来几个PMU监控特点:
N2的PMU事件采用分层编码体系,理解这个模式能快速定位目标事件:
| 事件类别 | 编码范围 | 典型事件示例 |
|---|---|---|
| L1指令缓存 | 0x01-0x1F | L1I_CACHE_REFILL(0x01) |
| L1数据缓存 | 0x20-0x4F | L1D_CACHE_WB(0x15) |
| L2缓存 | 0x50-0x7F | L2D_CACHE_REFILL_RD(0x52) |
| L3/系统缓存 | 0xA0-0xBF | L3_CACHE_RD(0xA0) |
| TLB相关 | 0x00-0x1F | L2D_TLB_REFILL(0x2D) |
特别注意:0x4000开始的编码是N2特有的微架构事件,如L1D_CACHE_LMISS_RD(0x39),这些事件在标准Arm架构手册中找不到说明
TLB(Translation Lookaside Buffer)是现代CPU虚拟化性能的关键,N2的PMU提供了从L1到L2 TLB的完整监控能力。
在KVM虚拟化环境中,我们通过以下命令监控客户机TLB行为:
bash复制perf stat -e armv8_pmuv3_0/l1d_tlb_refill/,armv8_pmuv3_0/l1d_tlb/ -C 0-15
关键发现:
N2的L2 TLB采用统一设计,但通过事件细分仍能区分指令和数据访问:
c复制// 典型监控代码片段
void monitor_tlb() {
struct perf_event_attr attr = {
.type = PERF_TYPE_RAW,
.config = 0x2F, // L2D_TLB
};
fd = perf_event_open(&attr, 0, -1, -1, 0);
read(fd, &count, sizeof(count));
}
注意事项:
L1D_CACHE_REFILL(0x03)是最重要的性能事件之一,它反映内存子系统延迟。我们在数据库负载中发现:
典型优化案例:
python复制# 优化前
for i in range(len):
arr[i] = 0 # 触发L1D_CACHE_REFILL_WR
# 优化后
dc_zva(arr, len) # 使用硬件指令,仅触发L1D_CACHE_WR
虽然事件名称带有"D",但N2的L2是统一缓存。重要发现:
CMN的SLC通过以下事件反映:
| CMN事件 | 对应CPU事件 | 关系 |
|---|---|---|
| RN_SLC_MISS | L3D_CACHE_REFILL | 直接相关 |
| HN_SLC_FILL | L2D_CACHE_WB | 写回触发 |
调优建议:
建立性能模型时需要组合事件:
内存延迟公式:
code复制内存周期 ≈ (L1D_CACHE_REFILL × L1命中延迟) +
(L2D_CACHE_REFILL × L2命中延迟) +
(L3D_CACHE_REFILL × 内存延迟)
缓存效率矩阵:
| 层级 | 命中率公式 | 优化阈值 |
|---|---|---|
| L1 | 1 - (REFILL/ACCESS) | <95% |
| L2 | 1 - (REFILL/L2D_CACHE) | <85% |
| SLC | HN_SLC_HIT/RN_SLC_REQ | <70% |
对于多CMN系统,需要同步所有芯片的PMU:
bash复制# 使用Arm SPE工具采集全路径数据
spe-collector -e cpu_cycles,l1d_cache_refill,l2d_cache_refill -o perf.data
注意:需要在内核配置CONFIG_ARM_SPE_PMU
现象:L1D_CACHE_WB计数异常低
原因:可能是Erratum #2280397影响(r0p1前版本)
解决:升级至r0p1或使用workaround:
c复制void apply_erratum_2280397() {
asm volatile("msr S3_0_C15_C1_2, %0" :: "r"(0x1000000));
}
在KVM中需要:
bash复制echo 1 > /sys/module/kvm/parameters/pmu_v3_enable
使用perf的--per-thread模式:
bash复制perf stat -e l1d_cache_refill -p <pid> -t <tid>
我们发现当线程共享L2缓存时,L2D_CACHE_REFILL会增加约25%
Linux perf:从5.15开始完整支持N2 PMU
bash复制perf list | grep armv8_pmuv3
Arm DS-5:提供图形化事件配置界面
自定义监控:
c复制// 直接访问PMU寄存器
uint64_t read_pmu(int counter) {
uint64_t val;
asm volatile("mrs %0, pmxevcntr%d_el0" : "=r"(val) : "i"(counter));
return val;
}
最后分享一个实测案例:在Redis集群中,通过监控L1D_TLB_REFILL_RD事件发现,使用1GB大页比2MB页面减少TLB失效次数达92%,整体延迟降低17%。这印证了N2 PMU数据对实际业务的价值。