IMC (内存集合计数器)

Anju T Sudhakar, 2019 年 5 月 10 日

基本概述

IMC(内存集合计数器)是一种硬件监控设施,可在 Nest 级别(这些是在片上但不在核心中)、核心级别和线程级别收集大量的硬件性能事件。

Nest PMU 计数器由在 OCC(片上控制器)复合体中运行的 Nest IMC 微代码处理。微代码收集计数器数据并将 Nest IMC 计数器数据移动到内存中。

核心和线程 IMC PMU 计数器在核心中处理。核心级别 PMU 计数器为我们提供每个核心的 IMC 计数器数据,而线程级别 PMU 计数器为我们提供每个 CPU 线程的 IMC 计数器数据。

OPAL 从 IMC 目录获取 IMC PMU 和支持的事件信息,并通过设备树传递给内核。事件的信息包含

  • 事件名称

  • 事件偏移

  • 事件描述

并且可能还包含

  • 事件比例

  • 事件单位

某些 PMU 的所有受支持事件可能具有通用的比例和单位值。对于这些情况,这些事件的比例和单位属性必须从 PMU 继承。

内存中的事件偏移是累积计数器数据的位置。

IMC 目录位于

https://github.com/open-power/ima-catalog

内核在设备树的 imc-counters 设备节点中发现 IMC 计数器信息,该节点具有兼容字段 ibm,opal-in-memory-counters。内核从设备树解析 PMU 及其事件的信息,并在内核中注册 PMU 及其属性。

IMC 示例用法

# perf list
[...]
nest_mcs01/PM_MCS01_64B_RD_DISP_PORT01/            [Kernel PMU event]
nest_mcs01/PM_MCS01_64B_RD_DISP_PORT23/            [Kernel PMU event]
[...]
core_imc/CPM_0THRD_NON_IDLE_PCYC/                  [Kernel PMU event]
core_imc/CPM_1THRD_NON_IDLE_INST/                  [Kernel PMU event]
[...]
thread_imc/CPM_0THRD_NON_IDLE_PCYC/                [Kernel PMU event]
thread_imc/CPM_1THRD_NON_IDLE_INST/                [Kernel PMU event]

查看 nest_mcs0/PM_MCS_DOWN_128B_DATA_XFER_MC0/ 的每个芯片数据

# ./perf stat -e "nest_mcs01/PM_MCS01_64B_WR_DISP_PORT01/" -a --per-socket

查看核心 0 的非空闲指令

# ./perf stat -e "core_imc/CPM_NON_IDLE_INST/" -C 0 -I 1000

查看“make”的非空闲指令

# ./perf stat -e "thread_imc/CPM_NON_IDLE_PCYC/" make

IMC 跟踪模式

POWER9 支持两种 IMC 模式,即累积模式和跟踪模式。在累积模式下,事件计数累积在系统内存中。然后,管理程序会定期或在请求时读取发布的计数。在 IMC 跟踪模式下,使用事件信息初始化 64 位跟踪 SCOM 值。跟踪 SCOM 中的 CPMCxSEL 和 CPMC_LOAD 指定要监视的事件和采样持续时间。在 CPMCxSEL 中的每次溢出时,硬件会快照程序计数器以及事件计数,并写入 LDBAR 指向的内存。

LDBAR 是一个 64 位特殊用途的每个线程寄存器,它具有指示硬件是配置为累积模式还是跟踪模式的位。

LDBAR 寄存器布局

0

启用/禁用

1

0:累积模式

1:跟踪模式

2:3

保留

4-6

PB 范围

7

保留

8:50

计数器地址

51:63

保留

TRACE_IMC_SCOM 位表示

0:1

SAMPSEL

2:33

CPMC_LOAD

34:40

CPMC1SEL

41:47

CPMC2SEL

48:50

BUFFERSIZE

51:63

保留

CPMC_LOAD 包含采样持续时间。SAMPSEL 和 CPMCxSEL 确定要计数的事件。BUFFERSIZE 指示内存范围。在每次溢出时,硬件会快照程序计数器以及事件计数,并更新内存,并重新加载 CMPC_LOAD 值以进行下一次采样。IMC 硬件不支持异常,因此如果内存缓冲区到达末尾,它会静默回绕。

当前,为跟踪模式监视的事件固定为周期。

跟踪 IMC 示例用法

# perf list
[....]
trace_imc/trace_cycles/                            [Kernel PMU event]

使用跟踪 IMC 事件记录应用程序/进程

# perf record -e trace_imc/trace_cycles/ yes > /dev/null
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.012 MB perf.data (21 samples) ]

生成的 perf.data 可以使用 perf report 读取。

使用 IMC 跟踪模式的优点

由于 IMC 跟踪模式快照程序计数器并更新到内存,因此避免了 PMI(性能监视中断)中断处理。这也为操作系统提供了一种无需 PMI 处理开销即可实时进行指令采样的方法。

使用 perf top 的性能数据,无论是否有跟踪 IMC 事件。

当在没有跟踪 IMC 事件的情况下执行 perf top 命令时,PMI 中断计数。

# grep PMI /proc/interrupts
PMI:          0          0          0          0   Performance monitoring interrupts
# ./perf top
...
# grep PMI /proc/interrupts
PMI:      39735       8710      17338      17801   Performance monitoring interrupts
# ./perf top -e trace_imc/trace_cycles/
...
# grep PMI /proc/interrupts
PMI:      39735       8710      17338      17801   Performance monitoring interrupts

也就是说,使用 trace_imc 事件时,PMI 中断计数不会增加。