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

因此,我一直希望自己编写这些小便计数器。有没有人有过操纵PEBS柜台的经验?具体来说,我一直在寻找良好的资源来了解如何对其进行编程。我已经阅读了英特尔文档并理解了步骤。但是我想了解一些示例程序。我已经通过以下github回购:-

https://github.com/pyrovski/powertools

但是我不确定如何以及从哪里开始。我还需要寻找其他好资料吗?任何有关理解和开始编程的好的资源的建议都将非常有帮助。

最佳答案

请不要在单次运行中混合使用跟踪和时序测量。

最快地运行Spec和跟踪所有内存访问都是不可能的。一次运行用于计时,另一次(更长,更慢)进行内存访问跟踪。

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第3B卷(这是用于PEBS编程的唯一好资源),以了解字段以及PEBS配置和输出的含义:
https://xem.github.io/minix86/manual/intel-x86-and-64-manual-vol3/o_fe12b1e2a880e0ce-734.html

18.15.7处理器基于事件的采样

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

(因此,重置值可能为负,等于-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)“表18-10”-只有L1 / L2 / DTLB丢失在Intel Core中具有PEBS事件。 (为您的CPU找到PEBS部分并搜索内存事件。具有PEBS功能的事件确实很少。)

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

英特尔的PMU编程指南也是PMU(硬件性能监视单元)的另一个很好的资源。它们对普通的PMU和PEBS都有简短的描述。有公开的“Nehalem Core PMU”,其中大多数仍对较新的CPU有用-https://software.intel.com/sites/default/files/m/5/2/c/f/1/30320-Nehalem-PMU-Programming-Guide-Core.pdf(并且有非核心PMU指南:E5-2600非核心PMU指南,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-这些不是您祖父的CPU性能计数器”

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

尝试在内存测试中找到具有不同记录率(1%/ 10%/ 50%)的实际(最大)开销,例如(最坏的内存记录开销情况,Arithmetic Intensity scaleRoofline model的左侧-STREAM为BLAS1,GUPS和memlat几乎是SpMV;实际任务通常不在规模之内):
  • STREAM test (linear access to memory)
  • RandomAccess(GUPS)测试
  • 一些内存延迟测试(memlat of 7zlat_mem_rdlmbench)。

  • 您是否要跟踪每个加载/存储命令,还是只想记录错过所有(某些)缓存并发送到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,尤其是Andi Kleen在pt上的博客:http://halobates.de/blog/p/410“具有Linux perf和gdb的英特尔处理器跟踪速查表”

    硬件中的PT支持:Broadwell(第五代Core,Xeon v4),开销更大。没有细粒度的时间安排。

    PS:研究SpecCPU内存访问的学者使用内存访问转储/跟踪,并且转储的生成速度很慢:
  • http://www.bu.edu/barc2015/abstracts/Karsli_BARC_2015.pdf-LLC未记录到脱机分析中,没有从跟踪运行中记录任何时间
  • http://users.ece.utexas.edu/~ljohn/teaching/382m-15/reading/gove.pdf-通过写入到额外的巨大跟踪缓冲区以进行定期(罕见)在线聚合来检测所有加载/存储。这样的检测速度是2倍或更慢,特别是对于内存带宽/延迟受限的内核。
  • http://www.jaleels.org/ajaleel/publications/SPECanalysis.pdf(由VSSAD,Intel Corporation的Aamer Jaleel提供)-基于引脚的检测-修改了程序代码,并检测了将内存访问元数据写入缓冲区的检测。这样的检测速度是2倍或更慢,特别是对于内存带宽/延迟受限的内核。该白皮书列出并解释了仪器开销和注意事项:

  • 仪器开销:仪器涉及
    动态或静态地将额外的代码注入(inject)到
    目标应用程序。附加代码导致
    应用程序花费额外的时间执行原始文件
    应用程序...此外,用于多线程
    应用程序,仪器可以修改命令的顺序
    在不同线程之间执行的指令
    应用。结果,IDS与多线程
    应用程序缺乏保真度

    缺乏投机:只能观察仪器
    在正确的执行路径上执行的指令。如
    结果,IDS可能无法支持错误路径...

    仅用户级别的流量:当前的二进制工具
    工具仅支持用户级检测。从而,
    内核密集型应用程序不适合
    用户级别的IDS。

    09-27 03:29