perf_events 列表中的核心 PMU 事件是什麼?
在 Linux 上搜尋可以監控的內容,但找不到是什麼?即,顯示事件如下:
perf_events``Kernel PMU event``perf version 3.13.11-ckt39``perf list
branch-instructions OR cpu/branch-instructions/ [Kernel PMU event]
總體有:
Tracepoint event Software event Hardware event Hardware cache event Raw hardware event descriptor Hardware breakpoint Kernel PMU event
我想了解它們是什麼,它們來自哪裡。我對所有人都有某種解釋,但
Kernel PMU event
項目。從perf wiki tutorial和Brendan Gregg 的頁面我得到:
Tracepoints
是最清楚的——這些是核心原始碼上的宏,它們是監控的探針點,它們是與ftrace
項目一起引入的,現在每個人都在使用Software
是核心的低級計數器和一些內部資料結構(因此,它們與跟踪點不同)Hardware event
是一些非常基本的 CPU 事件,在所有架構上都可以找到,並且很容易被核心訪問Hardware cache event
是暱稱Raw hardware event descriptor
- 它的工作原理如下據我所知,
Raw hardware event descriptor
更多(微?)特定於架構的事件比Hardware event
來自處理器監視單元(PMU)或給定處理器的其他特定功能的事件,因此它們僅在某些微架構上可用(假設“架構”表示“x86_64”,其餘的實現細節都是“微架構”);並且可以通過這些奇怪的描述符訪問它們以進行檢測rNNN [Raw hardware event descriptor] cpu/t1=v1[,t2=v2,t3 ...]/modifier [Raw hardware event descriptor] (see 'man perf-list' on how to encode it)
– 這些描述符,它們指向的事件等等都可以在處理器手冊中找到(perf wiki 中的 PMU 事件);
但是,當人們知道給定處理器上有一些有用的事件時,他們會給它一個暱稱並將其插入 linux
Hardware cache event
以便於訪問– 如果我錯了,請糾正我(奇怪的是,所有這些
Hardware cache event
都是關於something-loads
或something-misses
– 非常像實際處理器的記憶體..)
- 現在
Hardware breakpoint
mem:<addr>[:access] [Hardware breakpoint]
是一種硬體功能,可能是大多數現代架構所共有的,並且在調試器中用作斷點?(無論如何它可能是可Google搜尋的)
- 最後,
Kernel PMU event
我沒能上Google;它也沒有出現在 Brendan 的性能頁面中的事件列表中,所以它是新的嗎?
也許它只是專門來自 PMU 的硬體事件的暱稱?(為了便於訪問,它在事件列表中除了暱稱之外還有一個單獨的部分。)事實上,可能
Hardware cache events
是來自 CPU 記憶體的硬體事件的Kernel PMU event
暱稱和 PMU 事件的暱稱?(為什麼不叫它呢Hardware PMU event
?..)它可能只是新的命名方案——硬體事件的暱稱被分段了?這些事件指的是
cpu/mem-stores/
,加上一些linux版本事件在和中得到描述/sys/devices/
:# find /sys/ -type d -name events /sys/devices/cpu/events /sys/devices/uncore_cbox_0/events /sys/devices/uncore_cbox_1/events /sys/kernel/debug/tracing/events
–
debug/tracing
用於ftrace
和跟踪點,其他目錄完全匹配perf list
顯示為Kernel PMU event
.有人可以指出我是什麼
Kernel PMU events
或/sys/..events/
系統的一個很好的解釋/文件嗎?此外,是否/sys/..events/
有一些新的努力來系統化硬體事件或類似的東西?(那麼,Kernel PMU 就像“Kernel 的性能監控單元”。)附言
為了提供更好的上下文,沒有特權的執行
perf list
(未顯示跟踪點,但所有 1374 個都存在)以及Kernel PMU event
s 和Hardware cache event
s 的完整列表以及其他跳過:$ perf list List of pre-defined events (to be used in -e): cpu-cycles OR cycles [Hardware event] instructions [Hardware event] ... cpu-clock [Software event] task-clock [Software event] ... L1-dcache-load-misses [Hardware cache event] L1-dcache-store-misses [Hardware cache event] L1-dcache-prefetch-misses [Hardware cache event] L1-icache-load-misses [Hardware cache event] LLC-loads [Hardware cache event] LLC-stores [Hardware cache event] LLC-prefetches [Hardware cache event] dTLB-load-misses [Hardware cache event] dTLB-store-misses [Hardware cache event] iTLB-loads [Hardware cache event] iTLB-load-misses [Hardware cache event] branch-loads [Hardware cache event] branch-load-misses [Hardware cache event] branch-instructions OR cpu/branch-instructions/ [Kernel PMU event] branch-misses OR cpu/branch-misses/ [Kernel PMU event] bus-cycles OR cpu/bus-cycles/ [Kernel PMU event] cache-misses OR cpu/cache-misses/ [Kernel PMU event] cache-references OR cpu/cache-references/ [Kernel PMU event] cpu-cycles OR cpu/cpu-cycles/ [Kernel PMU event] instructions OR cpu/instructions/ [Kernel PMU event] mem-loads OR cpu/mem-loads/ [Kernel PMU event] mem-stores OR cpu/mem-stores/ [Kernel PMU event] ref-cycles OR cpu/ref-cycles/ [Kernel PMU event] stalled-cycles-frontend OR cpu/stalled-cycles-frontend/ [Kernel PMU event] uncore_cbox_0/clockticks/ [Kernel PMU event] uncore_cbox_1/clockticks/ [Kernel PMU event] rNNN [Raw hardware event descriptor] cpu/t1=v1[,t2=v2,t3 ...]/modifier [Raw hardware event descriptor] (see 'man perf-list' on how to encode it) mem:<addr>[:access] [Hardware breakpoint] [ Tracepoints not available: Permission denied ]
Google搜尋
ack
結束!我有一些答案。但首先讓我再澄清一下問題的目的:我想清楚地區分系統中的獨立程序及其性能計數器。例如,處理器的核心,非核心設備(最近了解),處理器上的核心或使用者應用程序,匯流排(=匯流排控制器),硬碟驅動器都是獨立的程序,它們不通過時鐘同步. 現在可能他們都有一些程序監控計數器(PMC)。我想了解計數器來自哪些程序。(它也有助於Google搜尋:事物的“供應商”將其歸零更好。)
此外,用於搜尋的設備:
Ubuntu 14.04
,linux 3.13.0-103-generic
,處理器Intel(R) Core(TM) i5-3317U CPU @ 1.70GHz
(從/proc/cpuinfo
,它有 2 個物理核心和 4 個虛擬核心——這裡的物理問題)。術語,問題涉及的事情
來自英特爾:
- 處理器是一個
core
設備(它是一個設備/程序)和一堆uncore
設備,core
是執行程序(時鐘,ALU,寄存器等)uncore
的設備,是放在晶片上的設備,靠近處理器以提高速度和低延遲(真正的原因是“因為製造商可以做到”);據我了解,它基本上是北橋,就像在 PC 主機板上一樣,加上記憶體;而 AMD 實際上將這些設備instead of
稱為 NorthBridge 非核心;ubox
這齣現在我的sysfs
$ find /sys/devices/ -type d -name events /sys/devices/cpu/events /sys/devices/uncore_cbox_0/events /sys/devices/uncore_cbox_1/events
– 是一個
uncore
設備,它管理最後一級記憶體(LLC,在命中 RAM 之前的最後一個);我有 2 個核心,因此有 2 個 LLC 和 2 個ubox
;
- 處理器監控單元 (PMU) 是一個單獨的設備,它監控處理器的操作並將其記錄在處理器監控計數器 (PMC) 中(計數記憶體未命中、處理器週期等);它們存在於
core
和uncore
設備上;那些core
通過rdpmc
(讀取 PMC)指令訪問;由於uncore
這些設備依賴於手頭的實際處理器,因此通過模型特定寄存器(MSR)訪問rdmsr
(自然);顯然,它們的工作流程是通過成對的寄存器完成的——1個寄存器組事件計數器計數,2個寄存器是計數器中的值;計數器可以配置為在一堆事件後遞增,而不僅僅是 1;+ 這些計數器中有一些中斷/技術注意到溢出;
- 更多可以在 Intel 的“IA-32 Software Developer’s Manual Vol 3B”第 18 章“PERFORMANCE MONITORING”中找到;
uncore
另外, “Architectural Performance Monitoring Version 1”版本(手冊中有1-4版本,我不知道哪個是我的處理器)的這些PMC的MSR格式在“圖18-1”中描述。 佈局IA32_PERFEVTSELx MSRs”(我的第 18-3 頁),以及“18.2.1.2 預定義架構性能事件”部分和“表 18-1。預定義架構性能事件的 UMask 和事件選擇編碼”,其中顯示了中顯示Hardware event
的事件perf list
。從linux核心:
- 核心有一個系統(抽象/層)用於管理不同來源的性能計數器,包括軟體(核心)和硬體,在
linux-source-3.13.0/tools/perf/design.txt
; 這個系統中的一個事件被定義為struct perf_event_attr
(文件linux-source-3.13.0/include/uapi/linux/perf_event.h
),它的主要部分可能是__u64 config
欄位——它可以包含特定於 CPU 的事件定義(那些 Intel 圖中描述的格式中的 64 位字)或核心的事件配置字的 MSB 表示其餘部分是否包含
$$ raw CPU’s or kernel’s event $$
核心事件定義為 7 位類型和 56 位事件標識符,
enum
在程式碼中是 -s,在我的例子中是:$ ak PERF_TYPE linux-source-3.13.0/include/ ... linux-source-3.13.0/include/uapi/linux/perf_event.h 29: PERF_TYPE_HARDWARE = 0, 30: PERF_TYPE_SOFTWARE = 1, 31: PERF_TYPE_TRACEPOINT = 2, 32: PERF_TYPE_HW_CACHE = 3, 33: PERF_TYPE_RAW = 4, 34: PERF_TYPE_BREAKPOINT = 5, 36: PERF_TYPE_MAX, /* non-ABI */
(
ak
是我的別名ack-grep
,這是ack
Debian 上的名稱;而且ack
很棒);在核心的原始碼中,我們可以看到諸如“註冊系統上發現的所有 PMU”之類的操作和結構類型
struct pmu
,它們被傳遞給類似的東西int perf_pmu_register(struct pmu *pmu, const char *name, int type)
——因此,可以將這個系統稱為“核心的 PMU”,這將是一種聚合系統上的所有 PMU;但是這個名字可以理解為核心執行的監控系統,會產生誤導;為了清楚起見,我們稱這個子系統
perf_events
;
- 與任何核心子系統一樣,可以將這個子系統導出到
sysfs
(這是為了導出核心子系統供人們使用的);這就是我的 - 導出的(部分?)子系統中的那些events
目錄;/sys/``perf_events
- 此外,使用者空間實用程序
perf
(內置於 linux)仍然是一個單獨的程序,並且有自己的抽象;它將使用者請求監視的事件表示為perf_evsel
(fileslinux-source-3.13.0/tools/perf/util/evsel.{h,c}
) - 此結構有一個欄位struct perf_event_attr attr;
,但也有一個欄位,struct cpu_map *cpus;
即實用程序如何perf
將事件分配給所有或特定 CPU。回答
- 實際上,是記憶體設備(英特爾設備的)
Hardware cache event
事件的“快捷方式” ,它們是特定於處理器的,可以通過協議訪問。並且在架構中更加穩定,據我所知,它從設備中命名事件。我的核心中沒有其他一些事件和計數器的“快捷方式”。所有其餘的——和——都是核心的事件。ubox``uncore``Raw hardware event descriptor``Hardware event``core``3.13``uncore``Software``Tracepoints
我想知道
core
sHardware event
是否通過相同的Raw hardware event descriptor
協議訪問。他們可能不會——因為計數器/PMU 位於 上core
,所以它的訪問方式可能不同。例如,使用該rdpmu
指令,而不是rdmsr
訪問uncore
. 但這並不重要。 2.Kernel PMU event
只是事件,它們被導出到sysfs
. 我不知道這是如何完成的(由核心自動在系統上發現所有 PMC,或者只是硬編碼的東西,如果我添加一個kprobe
– 它是否被導出?等等)。但主要的一點是,這些事件與內部系統Hardware event
中的任何其他事件相同。perf_event
我不知道那些
$ ls /sys/devices/uncore_cbox_0/events clockticks
是。
詳情
Kernel PMU event
搜尋程式碼導致:
$ ak "Kernel PMU" linux-source-3.13.0/tools/perf/ linux-source-3.13.0/tools/perf/util/pmu.c 629: printf(" %-50s [Kernel PMU event]\n", aliases[j]);
– 發生在函式中
void print_pmu_events(const char *event_glob, bool name_only) { ... while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, &pmu->aliases, list) {...} ... /* b.t.w. list_for_each_entry is an iterator * apparently, it takes a block of {code} and runs over some lost * Ruby built in kernel! */ // then there is a loop over these aliases and loop{ ... printf(" %-50s [Kernel PMU event]\n", aliases[j]); ... } }
並且
perf_pmu__scan
在同一個文件中:struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu) { ... pmu_read_sysfs(); // that's what it calls }
– 這也在同一個文件中:
/* Add all pmus in sysfs to pmu list: */ static void pmu_read_sysfs(void) {...}
就是這樣。
詳細資訊
Hardware event
和Hardware cache event
顯然,
Hardware event
來自英特爾所謂的“預定義架構性能事件”,18.2.1.2 in IA-32 Software Developer’s Manual Vol 3B。手冊的“18.1 性能監控概述”將它們描述為:第二類性能監控能力稱為架構性能監控。此類支持相同的計數和基於中斷的事件採樣用法,但可用事件集較少。架構性能事件的可見行為在處理器實現中是一致的。使用 CPUID.0AH 列舉架構性能監控功能的可用性。這些事件在第 18.2 節中討論。
– 另一種類型是:
從 Intel Core Solo 和 Intel Core Duo 處理器開始,有兩類性能監控功能。第一類支持使用計數或基於中斷的事件採樣來監控性能的事件。這些事件是非架構性的,並且因處理器型號而異…
這些事件確實只是指向底層“原始”硬體事件的連結,可以通過
perf
實用程序 as訪問Raw hardware event descriptor
。要檢查這一點,請查看
linux-source-3.13.0/arch/x86/kernel/cpu/perf_event_intel.c
:/* * Intel PerfMon, used on Core and later. */ static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly = { [PERF_COUNT_HW_CPU_CYCLES] = 0x003c, [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, [PERF_COUNT_HW_CACHE_REFERENCES] = 0x4f2e, [PERF_COUNT_HW_CACHE_MISSES] = 0x412e, ... }
– 並且
0x412e
在“LLC Misses”的“表 18-1. 預定義架構性能事件的 UMask 和事件選擇編碼”中找到:Bit Position CPUID.AH.EBX | Event Name | UMask | Event Select ... 4 | LLC Misses | 41H | 2EH
–
H
用於十六進制。所有 7 個都在結構中,加上[PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding *
. (命名有點不同,地址是一樣的。)然後
Hardware cache event
s 在結構中,例如(在同一個文件中):static __initconst const u64 snb_hw_cache_extra_regs [PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] = {...}
——沙橋應該是哪個?
其中之一 –
snb_hw_cache_extra_regs[LL][OP_WRITE][RESULT_ACCESS]
用 填充SNB_DMND_WRITE|SNB_L3_ACCESS
,從上面的 def-s 中:#define SNB_L3_ACCESS SNB_RESP_ANY #define SNB_RESP_ANY (1ULL << 16) #define SNB_DMND_WRITE (SNB_DMND_RFO|SNB_LLC_RFO) #define SNB_DMND_RFO (1ULL << 1) #define SNB_LLC_RFO (1ULL << 8)
應該等於
0x00010102
,但我不知道如何用一些表來檢查它。這給出了一個想法如何使用它
perf_events
:$ ak hw_cache_extra_regs linux-source-3.13.0/arch/x86/kernel/cpu/ linux-source-3.13.0/arch/x86/kernel/cpu/perf_event.c 50:u64 __read_mostly hw_cache_extra_regs 292: attr->config1 = hw_cache_extra_regs[cache_type][cache_op][cache_result]; linux-source-3.13.0/arch/x86/kernel/cpu/perf_event.h 521:extern u64 __read_mostly hw_cache_extra_regs linux-source-3.13.0/arch/x86/kernel/cpu/perf_event_intel.c 272:static __initconst const u64 snb_hw_cache_extra_regs 567:static __initconst const u64 nehalem_hw_cache_extra_regs 915:static __initconst const u64 slm_hw_cache_extra_regs 2364: memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs, 2365: sizeof(hw_cache_extra_regs)); 2407: memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs, 2408: sizeof(hw_cache_extra_regs)); 2424: memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs, 2425: sizeof(hw_cache_extra_regs)); 2452: memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, 2453: sizeof(hw_cache_extra_regs)); 2483: memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, 2484: sizeof(hw_cache_extra_regs)); 2516: memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); $
memcpy
s 是在 中完成的__init int intel_pmu_init(void) {... case:...}
。只是
attr->config1
有點奇怪。但它在那裡,在perf_event_attr
(同一個linux-source-3.13.0/include/uapi/linux/perf_event.h
文件):... union { __u64 bp_addr; __u64 config1; /* extension of config */ }; union { __u64 bp_len; __u64 config2; /* extension of config1 */ }; ...
它們
perf_events
通過呼叫int perf_pmu_register(struct pmu *pmu, const char *name, int type)
(定義在 中linux-source-3.13.0/kernel/events/core.c:
)在核心系統中註冊:
static int __init init_hw_perf_events(void)
(文件arch/x86/kernel/cpu/perf_event.c
)與呼叫perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu)
(filearch/x86/kernel/cpu/perf_event_intel_uncore.c
, 還有arch/x86/kernel/cpu/perf_event_amd_uncore.c
) with callret = perf_pmu_register(&pmu->pmu, pmu->name, -1);
所以最後,所有事件都來自硬體,一切正常。但是在這里人們可以注意到:為什麼我們有
LLC-loads
inperf list
和 notubox1 LLC-loads
,因為這些是硬體事件並且它們實際上來自ubox
es?這是
perf
實用程序及其perf_evsel
結構的問題:當您向其請求硬體事件時,perf
您定義了您想要從哪個處理器獲得它的事件(預設為全部),並且它perf_evsel
使用請求的事件和處理器進行設置,然後在聚合時對來自所有處理器的計數器求和perf_evsel
(或對它們進行一些其他統計)。可以在以下位置看到它
tools/perf/builtin-stat.c
:/* * Read out the results of a single counter: * aggregate counts across CPUs in system-wide mode */ static int read_counter_aggr(struct perf_evsel *counter) { struct perf_stat *ps = counter->priv; u64 *count = counter->counts->aggr.values; int i; if (__perf_evsel__read(counter, perf_evsel__nr_cpus(counter), thread_map__nr(evsel_list->threads), scale) < 0) return -1; for (i = 0; i < 3; i++) update_stats(&ps->res_stats[i], count[i]); if (verbose) { fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", perf_evsel__name(counter), count[0], count[1], count[2]); } /* * Save the full runtime - to allow normalization during printout: */ update_shadow_stats(counter, count); return 0; }
(因此,對於實用程序而言
perf
,“單個計數器”甚至不是 aperf_event_attr
,它是一種通用形式,適合 SW 和 HW 事件,它是您查詢的事件 - 相同的事件可能來自不同的設備並且它們被聚合.)還有一個通知:
struct perf_evsel
只包含 1struct perf_evevent_attr
,但它也有一個欄位struct perf_evsel *leader;
——它是嵌套的。中有一個“(分層)事件組”的特性perf_events
,當你可以將一堆計數器一起調度,以便它們可以相互比較等等。不確定它如何處理來自kernel
,core
,的獨立事件ubox
。但是這個嵌套perf_evsel
就是它了。而且,最有可能的是,這就是perf
同時管理多個事件的查詢的方式。