了解CYCLE_ACTIVITY。* Haswell性能监控事件

时间:2015-11-12 17:16:28

标签: intel performancecounter cpu-architecture cpu-cache perf

我正在尝试使用自上而下的微体系结构分析方法(TMAM)分析Intel Haswell CPU(英特尔®酷睿™i7-4900MQ)的执行情况,如{B章B.1和B.4节所述{3}}。 (如果需要,我将B.4中描述的Sandy Bridge公式调整为Haswell Microarchitecture。)

因此,我使用Perf执行性能计数器事件测量。有些结果我不明白:

  1. CPU_CLK_UNHALTED.THREAD_P< CYCLE_ACTIVITY.CYCLES_LDM_PENDING

  2. 这仅适用于少量测量,但仍然很奇怪。 PMU是否计算CYCLE_ACTIVITY.CYCLES_LDM_PENDING的停止周期?

    1. CYCLE_ACTIVITY.CYCLES_L2_PENDING> CYCLE_ACTIVITY.CYCLES_L1D_PENDINGCYCLE_ACTIVITY.STALLS_L2_PENDING> CYCLE_ACTIVITY.STALLS_L1D_PENDING
    2. 这适用于所有测量。当L1D高速缓存未命中时,负载会转移到L2高速缓存,对吧?因此早先错过L2的负载也错过了L1。这里没有计算L1指令高速缓存,但是*_L2_PENDING*_L1D_PENDING大100倍甚至大1000倍,可能不是那样。是否分别以某种方式测量了档位/周期?但是有这个公式:

      %L2_Bound = (CYCLE_ACTIVITY.STALLS_L1D_PENDING - CYCLE_ACTIVITY.STALLS_L2_PENDING) / CLOCKS

      因此CYCLE_ACTIVITY.STALLS_L2_PENDING<假定CYCLE_ACTIVITY.STALLS_L1D_PENDING(公式的结果必须为正)。 (这个公式的另一个原因是它应该是CYCLES而不是STALLS。但是这不能解决上面描述的问题。)那么如何解释呢?

      编辑:我的操作系统:Ubuntu 14.04.3 LTS,内核:3.13.0-65-通用x86_64,性能版本:3.13.11-ckt26

1 个答案:

答案 0 :(得分:1)

我将从问题的第二部分开始,即CYCLE_ACTIVITY.CYCLES_L2_PENDINGCYCLE_ACTIVITY.STALLS_L2_PENDING如何分别大于CYCLE_ACTIVITY.CYCLES_L1D_PENDINGCYCLE_ACTIVITY.STALLS_L1D_PENDING

首先,请注意%L2_Bound的公式来自《英特尔优化手册》的B.5节。该部分的第一段说:

  

本节介绍使用   性能监控事件。一些技术可以适应   对于其他微体系结构而言,大多数性能事件   特定于英特尔微体系结构代码名称Sandy Bridge

我的第一个直觉是预取与它有关(请参阅我的comment)。本段使我朝着正确的方向前进;这些事件可能代表了桑迪桥和哈斯韦尔的不同情况。它们在Haswell上的含义如下:

  

CYCLE_ACTIVITY.CYCLES_L1D_PENDING:使用未决的L1数据缓存进行循环   错过负载。 CYCLE_ACTIVITY.CYCLES_L2_PENDING:以待处理的L2周期   错过负载。 CYCLE_ACTIVITY.STALLS_L1D_PENDING:由于   L1数据缓存未加载。 CYCLE_ACTIVITY.STALLS_L2_PENDING:   加载错过的L2。

该手册还说,仅当禁用超线程时,才应使用L2的计数器。现在这就是它们在Sandy Bridge上的含义:

  

CYCLE_ACTIVITY.CYCLES_L1D_PENDING:每个周期都有一个未决   要求加载该线程,增加1。
  CYCLE_ACTIVITY.CYCLES_L2_PENDING:每个周期都有一个 MLC缺失   未完成的需求加载此线程,增加1。
  CYCLE_ACTIVITY.STALLS_L1D_PENDING:每个周期都有一个未决   要求加载此线程且未调度uops ,加1。
  CYCLE_ACTIVITY.STALLS_L2_PENDING:每个周期都有一个 MLC缺失   待处理的需求负载,并且没有在此线程上分配任何操作,递增   通过1。

有三个重要区别:

  • 某些Haswell事件仅在禁用HT时才有效。即使启用了HT,所有SNB事件都有效。
  • CYCLE_ACTIVITY.STALLS_L2_PENDING在HSW上计算L2处的负载丢失次数,但是在SNB上,它计算在L2处至少有一个需求负载丢失的周期数。
  • HSW事件包括所有访问,而不仅仅是需求负载。相比之下,SNB事件仅在需求负载下发生。

在HSW上,CYCLE_ACTIVITY.CYCLES_L2_PENDING可能比CYCLE_ACTIVITY.CYCLES_L1D_PENDING大,这是由于L1D预取器(和/或L2预取器,取决于预取器是否递增计数器)发出的未挂起负载对于相同级别的缓存)。同样,尽管它们计算不同的事物,但由于预取,CYCLE_ACTIVITY.STALLS_L2_PENDING可能比CYCLE_ACTIVITY.STALLS_L1D_PENDING大。 TLB预取和其他MMU缓存中的预取也可能会影响HSW上的这些性能事件。另一方面,在SNB上,可以确保CYCLE_ACTIVITY.STALLS_L2_PENDING <CYCLE_ACTIVITY.STALLS_L1D_PENDING,这就是%L2_Bound公式在SNB上有效的原因。

就像我在评论中说的那样,禁用HT和/或prefetching可能会“解决”您的问题。

相关:When L1 misses are a lot different than L2 accesses… TLB related?

关于问题的第一部分,即CPU_CLK_UNHALTED.THREAD_P如何小于CYCLE_ACTIVITY.CYCLES_LDM_PENDING。我能想到的一种解释是CYCLE_ACTIVITY.CYCLES_LDM_PENDING发生在从(某些)其他线程(特别是在同一物理内核上)发出的负载中,而不仅仅是停止的线程。我建议禁用HT,然后看看会发生什么。