关于如何对 PEBS(基于事件的精确采样)计数器进行编程的良好资源?

Good resources on how to program PEBS (Precise event based sampling) counters?

我一直在尝试记录程序的所有内存访问,据我所知这似乎是不可能的。我一直在尝试查看我可以在多大程度上记录至少大部分内存访问(如果不是全部)。所以我希望以这样一种方式对 PEBS 计数器进行编程,以便我可以看到所收集的内存访问样本数量的变化。我想知道我是否可以通过修改 PEBS 计数器的计数器重置值来做到这一点。 (通常这会变为零,但我想将其设置为更高的值)

所以我想自己对这些 pebs 计数器进行编程。有没有人有操作 PEBS 计数器的经验?具体来说,我正在寻找好的资源来了解如何对它们进行编程。我已经阅读了英特尔文档并了解了这些步骤。但是我想了解一些示例程序。我已经完成了以下 github 回购:-

https://github.com/pyrovski/powertools

但我不太确定,如何以及从哪里开始。我需要查看其他好的资源吗?任何有关了解和开始编程的好资源的建议都将非常有帮助。

请不要在单个 运行.

中混合跟踪和计时测量

根本不可能 拥有最快的 运行 规格和所有内存访问跟踪。做一个 运行 用于计时,另一个(更长,更慢)用于内存访问跟踪。


https://github.com/pyrovski/powertools中,收集事件的频率由pebs_init的reset_val参数控制:

https://github.com/pyrovski/powertools/blob/0f66c5f3939a9b7b88ec73f140f1a0892cfba235/msr_pebs.c#L72

void
pebs_init(int nRecords, uint64_t *counter, uint64_t *reset_val ){
    // 1. Set up the precise event buffering utilities.
    //  a.  Place values in the
    //      i.   precise event buffer base,
    //      ii.  precise event index
    //      iii. precise event absolute maximum,
    //      iv.  precise event interrupt threshold,
    //      v.   and precise event counter reset fields
    //      of the DS buffer management area.
    //
    // 2.  Enable PEBS.  Set the Enable PEBS on PMC0 flag 
    //  (bit 0) in IA32_PEBS_ENABLE_MSR.
    //
    // 3.  Set up the IA32_PMC0 performance counter and 
    //  IA32_PERFEVTSEL0 for an event listed in Table 
    //  18-10.

    // IA32_DS_AREA points to 0x58 bytes of memory.  
    // (11 entries * 8 bytes each = 88 bytes.)

    // Each PEBS record is 0xB0 byes long.
...
    pds_area->pebs_counter0_reset       = reset_val[0];
    pds_area->pebs_counter1_reset       = reset_val[1];
    pds_area->pebs_counter2_reset       = reset_val[2];
    pds_area->pebs_counter3_reset       = reset_val[3];
...

    write_msr(0, PMC0, reset_val[0]);
    write_msr(1, PMC1, reset_val[1]);
    write_msr(2, PMC2, reset_val[2]);
    write_msr(3, PMC3, reset_val[3]);

这个项目是访问PEBS的库,在项目中没有包含它的使用示例(因为我发现在tpatki的其他项目中只有一个disabled test)。

检查 intel SDM Manual Vol 3B(这是 PEBS 编程的唯一好资源) 字段的含义以及 PEBS 配置和输出: https://xem.github.io/minix86/manual/intel-x86-and-64-manual-vol3/o_fe12b1e2a880e0ce-734.html

18.15.7 Processor Event-Based Sampling

PEBS permits the saving of precise architectural information associated with one or more performance events in the precise event records buffer, which is part of the DS save area (see Section 17.4.9, “BTS and DS Save Area”). To use this mechanism, a counter is configured to overflow after it has counted a preset number of events. After the counter overflows, the processor copies the current state of the general-purpose and EFLAGS registers and instruction pointer into a record in the precise event records buffer. The processor then resets the count in the performance counter and restarts the counter. When the precise event records buffer is nearly full, an interrupt is generated, allowing the precise event records to be saved. A circular buffer is not supported for precise event records. ... After the PEBS-enabled counter has overflowed, PEBS record is recorded

(因此,重置值可能是负数,等于 -1000 表示每第 1000 个事件,-10 表示每第 10 个事件。计数器将递增并且 PEBS 在计数器溢出时写入。)

https://xem.github.io/minix86/manual/intel-x86-and-64-manual-vol3/o_fe12b1e2a880e0ce-656.html 18.4.4 基于处理器事件的采样 (PEBS) "Table 18-10" - 只有 L1/L2/DTLB 未命中在英特尔酷睿中有 PEBS 事件。 (为您的 CPU 找到 PEBS 部分并搜索内存事件。支持 PEBS 的事件非常罕见。)

因此,要记录更多事件,您可能需要将此函数的 reset 部分设置为较小的绝对值,例如 -50 或 -10。使用 PEBS 这可能有效(并尝试 perf -e cycles:upp -c 10 - 不要要求以如此高的频率分析内核,只有用户 - space :u 并要求使用 :pp 和使用 -c 10 请求 -10 计数器。perf 已为 MSR 和缓冲区解析实现了所有 PEBS 机制。

PMU(硬件性能监控单元)的另一个好资源也来自英特尔,PMU 编程指南。它们也对通常的 PMU 和 PEBS 进行了简短而紧凑的描述。有 public "Nehalem Core PMU",其中大部分对较新的 CPU 仍然有用 - https://software.intel.com/sites/default/files/m/5/2/c/f/1/30320-Nehalem-PMU-Programming-Guide-Core.pdf (And there are uncore PMU guides: E5-2600 Uncore PMU Guide, 2012 https://www.intel.com/content/dam/www/public/us/en/documents/design-guides/xeon-e5-2600-uncore-guide.pdf)

关于 PEBS 的外部 pdf:https://www.blackhat.com/docs/us-15/materials/us-15-Herath-These-Are-Not-Your-Grand-Daddys-CPU-Performance-Counters-CPU-Hardware-Performance-Counters-For-Security.pdf#page=23 PMC:为 PEBS 设置 - 来自 "Black Hat USA 2015 - These are Not Your Grand Daddy's CPU Performance Counters"


您可以从简短的程序(不是最近规范CPU的参考输入)开始,然后使用perflinux 工具 (perf_events) 找到记录的内存请求与所有内存请求的可接受比率。通过向事件说明符 record -e event:pp 添加 :p:pp 后缀,PEBS 与 perf 一起使用。也可以尝试使用 pmu-tools ocperf.py 来简化英特尔事件名称编码。

尝试在内存测试中找到不同记录比率 (1% / 10% / 50%) 的实际(最大)开销,例如(内存记录开销的最坏情况,Arithmetic Intensity scale of Roofline model 的左侧部分- STREAM 是 BLAS1,GUPS 和 memlat 几乎是 SpMV;真正的任务通常不会如此留在规模上):

您想跟踪每个 load/store 个命令,还是只想记录错过所有(某些)缓存并发送到 PC 的主 RAM 内存(到 L3)的请求?

为什么您不希望有任何开销并记录所有内存访问?这是不可能的,因为每个内存访问都有几个字节的跟踪记录到内存中。因此,启用内存跟踪(超过 10% 或 mem.access 跟踪)显然会限制可用内存带宽,并且程序会 运行 变慢。甚至可以注意到 1% 的跟踪,但它的影响(开销)较小。

您的 CPU E5-2620 v4 是 Broadwell-EP 14nm,因此它可能还有一些更早的 Intel PT 变体:https://software.intel.com/en-us/blogs/2013/09/18/processor-tracing https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/intel-pt.txt https://github.com/01org/processor-trace and especially Andi Kleen's blog on pt: http://halobates.de/blog/p/410 "Cheat sheet for Intel Processor Trace with Linux perf and gdb"

PT support in hardware: Broadwell (5th generation Core, Xeon v4) More overhead. No fine grained timing.

PS: 研究 SpecCPU 内存访问的学者与内存访问一起工作 dumps/traces, 转储生成缓慢:

Instrumentation Overhead: Instrumentation involves injecting extra code dynamically or statically into the target application. The additional code causes an application to spend extra time in executing the original application ... Additionally, for multi-threaded applications, instrumentation can modify the ordering of instructions executed between different threads of the application. As a result, IDS with multi-threaded applications comes at the lack of some fidelity

Lack of Speculation: Instrumentation only observes instructions executed on the correct path of execution. As a result, IDS may not be able to support wrong-path ...

User-level Traffic Only: Current binary instrumentation tools only support user-level instrumentation. Thus, applications that are kernel intensive are unsuitable for user-level IDS.