正在定制实现在 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
事件也是如此。
需要注意的是 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_PERFEVTSELx
和 IA32_PMCx
寄存器。
每一对 IA32_PERFEVTSELx
和 IA32_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),
........
}
0x01b7
在 INTEL_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事件测量的能力。