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

Performance 关于如何编程PEBS(基于事件的精确采样)计数器的良好资源?,performance,memory,cpu,processor,perf,Performance,Memory,Cpu,Processor,Perf,我一直在尝试记录一个程序的所有内存访问,这在我阅读时似乎是不可能的。我一直在试图了解,如果不是全部的话,我可以在多大程度上记录至少大部分的内存访问。因此,我希望以这样一种方式对PEBS计数器进行编程,以便能够看到所收集的内存访问样本数量的变化。我想知道是否可以通过修改PEBS计数器的计数器重置值来实现这一点。(通常为零,但我想将其设置为更高的值) 所以我想自己为这些pebs计数器编程。有人有操作PEBS计数器的经验吗?具体来说,我正在寻找好的资源,看看如何编程。我已经阅读了Intel文档并理解了

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

所以我想自己为这些pebs计数器编程。有人有操作PEBS计数器的经验吗?具体来说,我正在寻找好的资源,看看如何编程。我已经阅读了Intel文档并理解了步骤。但我想了解一些示例程序。我已通过以下github回购协议:-

但我不太确定,如何开始,从哪里开始。有没有其他我需要寻找的好消息来源?任何关于了解和开始编程的好资源的建议都将非常有用。

请不要在单次运行中混合跟踪和计时测量。 这是不可能的两个最快的运行规范和所有的内存访问跟踪。一次运行计时,另一次运行(更长、更慢)内存访问跟踪


在中,收集事件的频率由
pebs_init
的reset_val参数控制:

该项目是访问PEB的库,并且在项目中没有使用它的示例(正如我在tpatki的其他项目中发现的那样)

查看第3B卷(这是PEBS编程的唯一好资源)了解字段和PEBS配置和输出的含义:

18.15.7基于处理器事件的采样

PEBS允许将与一个或多个性能事件相关的精确体系结构信息保存在精确事件记录缓冲区中,该缓冲区是DS保存区的一部分(见第17.4.9节“BTS和DS保存区”)。 要使用此机制,计数器被配置为在对预设数量的事件计数后溢出。计数器溢出后,处理器将通用寄存器和EFLAGS寄存器以及指令指针的当前状态复制到精确事件记录缓冲区中的记录中。然后处理器重置性能计数器中的计数并重新启动计数器。当精确事件记录缓冲区几乎满时,将生成一个中断,允许保存精确事件记录。精确事件不支持循环缓冲区 记录。 ... PEBS启用计数器溢出后,PEBS 记录被记录

(所以,重置值可能是负数,每1000个事件等于-1000,每10个事件等于-10。计数器将递增,PEB写入计数器溢出。)

和18.4.4处理器基于事件的采样(PEBS)“表18-10”-Intel Core中只有L1/L2/DTLB未命中具有PEBS事件。(查找CPU的PEBS部分并搜索内存事件。支持PEBS的事件非常罕见。)

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

PMU(硬件性能监控单元)的另一个很好的资源也来自《英特尔PMU编程指南》。它们对通常的PMU和PEB也有简短而紧凑的描述。有公开的“Nehalem Core PMU”,其中大部分对较新的CPU仍然有用-(还有uncore PMU指南:E5-2600 uncore PMU指南,2012)

关于PEB的外部pdf:PMCs:为PEB设置-来自“Black Hat USA 2015-这些不是您祖父的CPU性能计数器”


您可以从短而简单的程序开始(不是最新SpecCPU的ref输入),然后使用
perf
linux工具(perf\u事件)查找记录的内存请求与所有内存请求的可接受比率。通过向事件说明符
记录-e事件:pp
添加
:p
:pp
后缀,PEBS与
perf
一起使用。另外,请尝试更简单的英特尔事件名称编码

在内存测试中,尝试找出不同记录比率(1%/10%/50%)下的实际(最大)开销,如(内存记录开销的最坏情况,流的左侧部分为BLAS1,GUPS和memlat几乎为SpMV;实际任务通常不在规模上):

  • ,
  • 随机访问(GUPS)测试
  • 一些内存延迟测试(,of)
您想跟踪每个加载/存储命令,还是只想记录错过所有(部分)缓存并发送到PC主RAM内存(到L3)的请求

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

您的CPU E5-2620 v4是Broadwell EP 14nm,因此它可能也有一些早期版本的英特尔PT:特别是Andi Kleen的博客:“Linux性能和gdb英特尔处理器跟踪备忘单”

硬件方面的PT支持:Broadwell(第五代核心,Xeon v4)的开销更大。没有细粒度的定时

PS:研究SpecCPU内存访问的学者使用内存访问
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]);