在 perf 事件组中只有 2 个 PERF_TYPE_HW_CACHE 事件。

问题描述 投票:1回答:1

正在定制实现在 perf_event_open 我需要监控多个 PERF_TYPE_HW_CACHE 并发。

Intel手册上说,我的CPU的架构每个线程有4个可编程计数器(如果禁用HyperThreading,则有8个)。所以我把 PERF_TYPE_HW_CACHE 将选择的事件纳入1个香水事件组,其中包含 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_GROUP, LLC2_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 事件也是如此。

linux linux-kernel cpu-cache perf intel-pmu
1个回答
2
投票

需要注意的是 perf 允许同时测量2个以上的PERF_TYPE_HW_CACHE事件,例外情况是测量 LLC-cache 事件。

我们的期望是,当有4个通用硬件计数器和3个固定用途硬件计数器时,4个HW缓存事件(默认为 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

CPU属于 skylake/kaby lake 家族的微架构和其他一些架构,允许您测量 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 MSRs可以看到 此处.

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 和掩码 01. 该事件代码 0x01b7 映射到LLC-cache事件,可以看出 此处 -

[ 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可见 此处. 上面指定的函数,循环浏览所有 "额外寄存器 "的数组,并将事件->config(其中包含原始事件id)与非核心响应MSR关联起来。

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

离核寄存器的性质是对称的,所以当第一个MSR--。MSR_OFFCORE_RSP_0 寄存器忙。perf 使用第二种选择MSR。MSR_OFFCORE_RSP_1 用于测量另一个非核心LLC事件。该功能 此处 有助于做到这一点。

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-cache事件测量的能力。

© www.soinside.com 2019 - 2024. All rights reserved.