[英]only 2 PERF_TYPE_HW_CACHE events in perf event group
在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_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 個固定用途硬件計數器時,可以在 perf 中測量 4 個 HW 緩存事件(默認為RAW
事件),無需多路復用,超線程 ON 。
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
事件。 除了對IA32_PERFEVTSELx
和IA32_PMCx
寄存器進行編程外,監視OFFCORE_RESPONSE
事件還需要編程額外的 MSR,特別是MSR_OFFCORE_RSP0
(MSR 地址 1A6H)和MSR_OFFCORE_RSP1
(MSR 地址 1A7H)。
每對IA32_PERFEVTSELx
和IA32_PMCx
寄存器將與上述 MSR 之一相關聯,以測量 LLC 緩存事件。
可以在此處查看OFFCORE_RESPONSE
MSR 的定義。
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
和 umask 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
將始終從 map 到MSR_OFFCORE_RSP_0
,如下所示。 上面指定的 function 循環遍歷所有“額外寄存器”的數組,並將 event->config(包含原始事件 id)與核心響應 MSR 相關聯。
因此,這意味着一次只能測量一個事件,因為只有一個 MSR - MSR_OFFCORE_RSP_0
可以映射到LLC-cache
事件。 但事實並非如此!
核心外寄存器本質上是對稱的,因此當第一個 MSR - MSR_OFFCORE_RSP_0
寄存器忙時, perf
使用第二個替代 MSR MSR_OFFCORE_RSP_1
來測量另一個核心外 LLC 事件。 這里的 function 有助於做到這一點。
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 緩存事件測量的能力。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.