【问题标题】:only 2 PERF_TYPE_HW_CACHE events in perf event groupperf 事件组中只有 2 个 PERF_TYPE_HW_CACHE 事件
【发布时间】:2020-09-07 01:06:06
【问题描述】:

perf_event_open 之上进行自定义实现我需要同时监控多个PERF_TYPE_HW_CACHE

英特尔手册指出,对于我的 CPU 架构,每个线程有 4 个可编程计数器(如果禁用超线程,则为 8 个)。因此,我将选择的 PERF_TYPE_HW_CACHE 事件分组为 1 个 perf 事件组,其中包含 PERF_TYPE_HW_CACHE 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 组,每组 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 事件也会发生同样的情况。

【问题讨论】:

  • 您使用的是什么 CPU 和内核版本? (这看起来像是PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE concurrent monitoring 的后续行动,以防任何人试图回答这个问题。)
  • 另外,您是否禁用了 Linux 的 NMI 看门狗 (sysctl kernel/nmi_watchdog = 0) 以释放每个逻辑核心的第 4 个硬件性能计数器?
  • 嗨,彼得。是的,确实,这是一种后续,但我想更具体... CPU:Kaby Lake,内核:4.15.0-74-generic,nmi_watchdog = 0。谢谢

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


【解决方案1】:

请注意,perf 确实允许同时测量超过 2 个 PERF_TYPE_HW_CACHE 事件,但LLC-cache 事件的测量除外。

期望是,当有 4 个通用和 3 个固定用途时 硬件计数器,性能中的 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),
    ........
}

INTEL_UEVENT_EXTRA_REG 调用中的0x01b7 指的是事件代码b7 和umask 01。此事件代码 0x01b7 映射到 LLC-cache 事件,可以看到 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;
}

Kaby-Lake 系列微架构仅存在 2 个内核外寄存器,这阻碍了在没有任何多路复用的情况下同时针对超过 2 个 LLC 缓存事件测量的能力。

【讨论】:

    猜你喜欢
    • 2020-07-22
    • 1970-01-01
    • 1970-01-01
    • 2019-06-10
    • 1970-01-01
    • 2020-12-18
    • 2020-05-17
    • 1970-01-01
    • 2017-12-15
    相关资源
    最近更新 更多