伪共享与缓存行竞争
当多个处理器核心反复访问同一条缓存行时,这条缓存行会在核间来回迁移,每次迁移都要等待一致性协调,这就是伪共享。它的典型特征是:线程数增加而性能不升。该工具基于缓存一致性事件(命中已修改数据)把这笔开销归到具体的缓存行、地址与参与竞争的进程上。
基本信息
| 适用平台 | Linux,依赖支持一致性事件的硬件 |
|---|---|
| 采集方式 | 记录缓存一致性相关事件后生成报告 |
| 聚合维度 | 缓存行地址、参与的进程与访问类型 |
| 常用参数 | 整机范围记录、按条件排序输出 |
| 关键前提 | 硬件与内核支持相应性能事件 |
典型使用场景
- 多线程服务扩展性差:增加线程后吞吐不升反降。
- 定位共享计数器、统计字段与相邻变量造成的竞争。
- 验证结构调整(对齐、填充)之后竞争是否下降。
- 把核间竞争与跨节点访存问题区分开。
- 评估无锁结构是否真的消除了竞争。
记录与报告
记录与报告
perf c2c record -a -- sleep 5 # 整机记录缓存一致性事件
perf c2c report --stats # 先看汇总统计
perf c2c report --stdio | head -40 # 完整表格,先看竞争次数最高的行
perf c2c report --stdio -c pid,iaddr --sort=hitm # 按命中修改次数排序,聚焦竞争
# 输出按缓存行聚合,可定位参与竞争的地址与进程报告关键信息
| 信息 | 含义 | 判读要点 |
|---|---|---|
| 缓存行地址 | 发生竞争的缓存行 | 结合符号定位共享变量 |
| 参与进程 | 访问该行的进程与线程 | 多个线程出现在同一行即竞争 |
| 命中修改次数 | 核间迁移次数 | 数值高的行优先处理 |
| 访问类型 | 读或写 | 写共享变量最容易产生竞争 |
硬件不支持相应事件时记录会为空,这是能力问题不是结论;先确认平台支持,再决定是否用它。必要时用程序内的缓存行对齐与结构拆分来验证猜测。
跨处理器节点的内存访问延迟与缓存行竞争都会表现为「多线程变慢」,两者的处置完全不同:前者调亲和性与放置策略,后者改数据结构布局。