聚苯乙烯

聚苯乙烯

正在寻找什么可以perf_events在Linux上监控,我找不到什么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 教程布伦丹·格雷格的页面我明白了:

  • 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-loadssomething-misses-- 非常像实际处理器的缓存..)

  • 现在Hardware breakpoint

    mem:<addr>[:access]                                [Hardware breakpoint]
    

    是一种硬件功能,这可能是大多数现代体系结构所共有的,并且可以用作调试器中的断点? (无论如何可能它是谷歌搜索的)

  • 最后,Kernel PMU event我没能用谷歌搜索;

    它也没有出现在Brendan 性能页面中的事件列表,所以这是新的?

    也许这只是专门来自 PMU 的硬件事件的昵称? (为了便于访问,除了昵称之外,事件列表中还有一个单独的部分。)事实上,Hardware cache events昵称可能是来自 CPU 缓存的硬件事件,也是Kernel PMU eventPMU 事件的昵称吗? (为什么不Hardware PMU event这么称呼它?..)这可能只是新的命名方案——硬件事件的昵称被分段了?

    这些事件指的是cpu/mem-stores/, plus 之类的东西,因为一些 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就相当于“内核的性能监控单元”。)

聚苯乙烯

为了提供更好的上下文,非特权运行perf list(未显示跟踪点,但所有 1374 个跟踪点都在那里),并跳过了Kernel PMU events 和s 的完整列表:Hardware cache event

$ 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 ]

答案1

谷歌搜索和ack-ing结束了!我有一些答案。

但首先让我再澄清一下问题的目的:我想清楚地区分系统中的独立进程及其性能计数器。例如,处理器的核心、非核心设备(最近了解到)、处理器上的内核或用户应用程序、总线(=总线控制器)、硬盘驱动器都是独立的进程,它们不被时钟同步。如今,它们可能都有一些进程监控计数器(PMC)。我想了解计数器来自哪些进程。 (这对于谷歌搜索也很有帮助:事物的“供应商”可以更好地将其归零。)

另外,用于搜索的装备:Ubuntu 14.04linux 3.13.0-103-generic、 处理器Intel(R) Core(TM) i5-3317U CPU @ 1.70GHz(来自/proc/cpuinfo,它有 2 个物理核心和 4 个虚拟核心 - 这里的物理问题)。

术语、问题涉及的内容

来自英特尔:

  • 处理器是一个core设备(它是 1 个设备/进程)和一堆uncore设备core是运行程序的(时钟、ALU、寄存器等),uncore是放置在芯片上的设备,靠近处理器以实现速度和低延迟(真正的原因是“因为制造商可以做到”);据我了解,它基本上是北桥,就像 PC 主板上的一样,加上缓存; AMD 实际上称这些设备北桥为instead of“非核心”;

  • 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) 中(对缓存未命中、处理器周期等进行计数);它们存在于coreuncore设备上;这些core是通过rdpmc(读PMC)指令访问的;由于uncore这些设备依赖于手头的实际处理器,因此可以通过(自然地)通过模型特定寄存器(MSR)访问rdmsr

    显然,它们的工作流程是通过寄存器对完成的——1个寄存器设置计数器计数哪些事件,2个寄存器是计数器中的值;计数器可以配置为在一堆事件发生后递增,而不仅仅是 1; + 有一些中断/技术注意到这些计数器溢出;

  • 更多内容可以在 Intel 的《IA-32 Software Developer's Manual Vol 3B》第 18 章“性能监控”中找到;

    另外,“架构性能监控版本1”版本的这些PMC的MSR具体格式uncore(手册中有版本1-4,我不知道哪一个是我的处理器)在“图18-1.布局”中描述IA32_PERFEVTSELx MSR”(我的第 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(file linux-source-3.13.0/include/uapi/linux/perf_event.h),其主要部分可能是__u64 config字段——它可以保存特定于 CPU 的事件定义(Intel 图中描述的格式的 64 位字)或内核的事件

    配置字的 MSB 表示其余部分是否包含[原始 CPU 或内核事件]

    内核事件定义为 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是我的别名,它是Debian 上的ack-grep名称;非常棒);ackack

    在内核的源代码中,我们可以看到诸如“注册系统上发现的所有 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(文件linux-source-3.13.0/tools/perf/util/evsel.{h,c})——该结构有一个字段struct perf_event_attr attr;,但也有一个类似于实用程序struct cpu_map *cpus;如何perf将事件分配给所有或特定 CPU 的字段。

回答

  1. 事实上,它们是高速缓存设备(英特尔设备)Hardware cache event事件的“快捷方式” ,它们是特定于处理器的,并且可以通过协议进行访问。并且在架构内更加稳定,据我所知,它命名了设备中的事件。我的内核中没有其他一些事件和计数器的“快捷方式”。所有其余的 -和- 都是内核的事件。uboxuncoreRaw hardware event descriptorHardware eventcore3.13uncoreSoftwareTracepoints

    我想知道 是否是core通过Hardware 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 eventHardware cache event

显然,这Hardware event来自英特尔所谓的“预定义架构性能事件”,IA-32 软件开发人员手册第 3B 卷中的 18.2.1.2。手册的“18.1性能监控概述”将它们描述为:

第二类性能监控功能称为架构性能监控。此类支持相同的计数和基于中断的事件采样用法,以及较小的可用事件集。架构性能事件的可见行为在处理器实现之间是一致的。使用 CPUID.0AH 枚举架构性能监控功能的可用性。这些事件在 18.2 节中讨论。

-- 另一种类型是:

从英特尔酷睿单核和英特尔酷睿双核处理器开始,有两类性能监控功能。第一类支持使用计数或基于中断的事件采样来监视性能的事件。这些事件是非体系结构的,并且因处理器型号而异......

这些事件实际上只是到底层“原始”硬件事件的链接,可以通过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可以在“表 18-1.预定义架构性能事件的 UMask 和事件选择编码”中找到“LLC 未命中”:

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 events 的结构如下(在同一文件中):

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));
$

smemcpy是在 中完成的__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)(文件arch/x86/kernel/cpu/perf_event_intel_uncore.c,也有arch/x86/kernel/cpu/perf_event_amd_uncore.c)与调用ret = perf_pmu_register(&pmu->pmu, pmu->name, -1);

最后,所有事件都来自硬件,一切正常。但这里人们可能会注意到:为什么我们有LLC-loadsinperf list和 not ubox1 LLC-loads,因为这些是硬件事件并且它们实际上来自uboxes ?

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“单个计数器”甚至不是perf_event_attr,它是一种通用形式,适合软件和硬件事件,它是您查询的事件 - 相同的事件可能来自不同的设备,并且它们被聚合.)

另请注意:struct perf_evsel仅包含 1 struct perf_evevent_attr,但它还有一个字段struct perf_evsel *leader;——它是嵌套的。中有一个“(分层)事件组”的功能perf_events,当您可以将一堆计数器分派在一起时,以便它们可以相互比较等等。不确定它如何处理来自kernel, core,的独立事件ubox。但这个嵌套就是perf_evsel这样了。而且,最有可能的是,这就是如何perf管理多个事件的查询。

相关内容