linux - perf 事件组中只有 2 个 PERF_TYPE_HW_CACHE 事件

标签 linux linux-kernel cpu-cache perf intel-pmu

perf_event_open 之上处理自定义实现我需要监控多个 PERF_TYPE_HW_CACHE同时。

Intel 手册指出,对于我的 CPU 架构,每个线程有 4 个可编程计数器(如果禁用了超线程,则为 8 个)。所以我将 PERF_TYPE_HW_CACHE 分组选择的事件分为 1 个包含 PERF_TYPE_HW_CACHE 的 perf 事件组4 个事件 ( LLC_GROUP )。

我进行了第一个实验,得到了以下结果:

LLC_GROUP of thread 2 | time Enabled: 3190370379, time Running: 3017
HW_CACHE_LLC_READ_MISSES = 0
HW_CACHE_LLC_WRITE_MISSES = 0
HW_CACHE_LLC_READS = 0
HW_CACHE_LLC_WRITES = 0

从上面的结果来看,很明显 PMU 并不“适合”所有 4 个事件。我们还观察到一个“奇怪的”多路复用,但没有实际结果。

因此,作为下一步,我将 4 个事件组分成 2 个事件组/组( LLC_GROUPLLC2_GROUP ),我得到的结果如下:
LLC_GROUP of thread 2 | time Enabled: 2772569406, time Running: 1396022331
HW_CACHE_LLC_READ_MISSES = 102117
HW_CACHE_LLC_WRITE_MISSES = 9624295
LLC2_GROUP of thread 2 | time Enabled: 2772571024, time Running: 1376575096
HW_CACHE_LLC_READS = 22020658
HW_CACHE_LLC_WRITES = 18156060

使用此配置,我们再次观察到 PMU 不“适合” 4 PERF_TYPE_HW_CACHE同时,但这次(预期的)多路复用正在发生。

有没有人有任何解释?

这种行为对我来说看起来很奇怪,因为我能够监控多个 PERF_TYPE_HARDWARE没有多路复用的事件(最多 6 个),我希望 PERF_TYPE_HW_CACHE 也会发生同样的情况。事件也是如此。

最佳答案

请注意,perf允许同时测量超过 2 个 PERF_TYPE_HW_CACHE 事件,异常(exception)是测量 LLC-cache事件。

期望是,当有 4 个通用和 3 个固定用途时
硬件计数器,perf 中的 4 个硬件缓存事件(默认为 RAW 事件)无需多路复用即可测量,使用 超线程开启 .

sudo perf stat -e L1-icache-load-misses,L1-dcache-stores,L1-dcache-load-misses,dTLB-load-misses sleep 2

 Performance counter stats for 'sleep 2':

            26,893      L1-icache-load-misses                                       
            98,999      L1-dcache-stores                                            
            14,037      L1-dcache-load-misses                                       
               723      dTLB-load-misses                                            

       2.001732771 seconds time elapsed

       0.001217000 seconds user
       0.000000000 seconds sys


当您尝试测量针对 LLC-cache 的事件时会出现此问题。 .它似乎只测量 2 LLC-cache特定事件,并发,没有多路复用。
sudo perf stat -e LLC-load-misses,LLC-stores,LLC-store-misses,LLC-loads sleep 2

 Performance counter stats for 'sleep 2':

             2,419      LLC-load-misses           #    0.00% of all LL-cache hits   
             2,963      LLC-stores                                                  
     <not counted>      LLC-store-misses                                              (0.00%)
     <not counted>      LLC-loads                                                     (0.00%)

       2.001486710 seconds time elapsed

       0.001137000 seconds user
       0.000000000 seconds sys


属于 skylake/kaby lake 的 CPU微架构家族和其他一些,让您可以衡量 OFFCORE RESPONSE事件。监控 OFFCORE_RESPONSE事件需要编程额外的 MSR,特别是 MSR_OFFCORE_RSP0 (MSR 地址 1A6H)和 MSR_OFFCORE_RSP1 (MSR 地址 1A7H),除了编程对IA32_PERFEVTSELxIA32_PMCx寄存器。

每双IA32_PERFEVTSELxIA32_PMCx寄存器将与上述 MSR 之一相关联,以测量 LLC 缓存事件。
OFFCORE_RESPONSE的定义可以看到 MSR here .
static struct extra_reg intel_skl_extra_regs[] __read_mostly = {
    INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0),
    INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1),
    ........
}
0x01b7INTEL_UEVENT_EXTRA_REG调用指的是事件代码 b7和 umask 01 .此事件代码 0x01b7映射到 LLC 缓存事件,可以看出 here ——
[ C(LL  ) ] = {
    [ C(OP_READ) ] = {
        [ C(RESULT_ACCESS) ] = 0x1b7,   /* OFFCORE_RESPONSE */
        [ C(RESULT_MISS)   ] = 0x1b7,   /* OFFCORE_RESPONSE */
    },
    [ C(OP_WRITE) ] = {
        [ C(RESULT_ACCESS) ] = 0x1b7,   /* OFFCORE_RESPONSE */
        [ C(RESULT_MISS)   ] = 0x1b7,   /* OFFCORE_RESPONSE */
    },
    [ C(OP_PREFETCH) ] = {
        [ C(RESULT_ACCESS) ] = 0x0,
        [ C(RESULT_MISS)   ] = 0x0,
    },
 },

事件0x01b7将始终映射到 MSR_OFFCORE_RSP_0 ,可以看出 here .上面指定的函数循环遍历所有“额外寄存器”的数组,并将 event->config(包含原始事件 ID)与非核心响应 MSR 相关联。

因此,这意味着一次只能测量一个事件,因为只有一个 MSR - MSR_OFFCORE_RSP_0可以映射到 LLC-cache事件。但事实并非如此!

非核心寄存器本质上是对称的,所以当第一个 MSR - MSR_OFFCORE_RSP_0注册忙,perf使用第二种替代 MSR,MSR_OFFCORE_RSP_1用于测量另一个非核心 LLC 事件。此功能here有助于做到这一点。
static int intel_alt_er(int idx, u64 config)
{
    int alt_idx = idx;

    if (!(x86_pmu.flags & PMU_FL_HAS_RSP_1))
        return idx;

    if (idx == EXTRA_REG_RSP_0)
        alt_idx = EXTRA_REG_RSP_1;

    if (idx == EXTRA_REG_RSP_1)
        alt_idx = EXTRA_REG_RSP_0;

    if (config & ~x86_pmu.extra_regs[alt_idx].valid_mask)
        return idx;

    return alt_idx;
}

仅存在 2 个非核心寄存器,用于 Kaby-Lake微架构家族阻碍了在没有任何多路复用的情况下同时针对 2 个以上 LLC 缓存事件测量的能力。

关于linux - perf 事件组中只有 2 个 PERF_TYPE_HW_CACHE 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61916933/

相关文章:

c - 构建linux内核UML错误

linux - 如何通过分析 OProfile 的输出来优化内核启动时间?

cuda - 跨 CUDA 内核的 L1 缓存持久性

linux - 验证文件是否已创建 shell

python - Django 无法上传到 777 权限文件夹

python - 当线程等待 stdout 时继续运行 python 脚本

c - SMP 架构中的 pthread_create(3) 和内存同步保证

linux screen 分离和注销

linux:写入文件的数据是否保证对其他进程可见?

c - 如何在c中的两个程序之间共享库