【问题标题】:Understanding CYCLE_ACTIVITY.* Haswell Performance-Monitoring Events了解 CYCLE_ACTIVITY.* Haswell 性能监控事件
【发布时间】:2016-02-14 03:03:00
【问题描述】:

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

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

  1. CPU_CLK_UNHALTED.THREAD_P CYCLE_ACTIVITY.CYCLES_LDM_PENDING

这仅适用于少数测量,但仍然很奇怪。 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

这适用于所有测量。当 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-generic x86_64,性能版本:3.13.11-ckt26

【问题讨论】:

  • 您的操作系统和 perf 版本是什么?
  • 操作系统:Ubuntu 14.04.3 LTS,性能版本:3.13.11-ckt26
  • 您是否检查过您的 perf 版本是否与您的内核匹配?
  • 我的内核版本是 3.13.0-65-generic x86_64。软件包 linux-tools-common(3.13.0-65.105, all) 和 linux-tools-3.13.0-65-generic(3.13.0-65.105, amd64) 安装在系统上。我想那么 perf 版本是否适合我的内核?或者如何检查我的 perf 版本是否正确?
  • 尝试禁用超线程和/或预取,看看会发生什么。同时测量 TLB 未命中。

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


【解决方案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)。这一段把我推向了正确的方向;这些事件在 Sandy Bridge 和 Haswell 中可能代表不同的事物。这是他们在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-miss 挂起的需求加载此线程,递增 1。
CYCLE_ACTIVITY.STALLS_L1D_PENDING:每个周期都有一个未命中未决 需求加载这个线程并且没有发送微指令,增加1。
CYCLE_ACTIVITY.STALLS_L2_PENDING:每个循环都有一个MLC-miss 待处理的需求负载并且没有在此线程上调度微指令,递增 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 可能会“解决”您的问题。

实际上,Mobile Haswell 处理器的英特尔规范更新文档提到了两个影响CYCLES_L2_PENDING 的错误:

  • HSM63:CYCLES_L2_PENDING 在 Haswell 上的预期行为是仅计算需求负载,但在 SMT 模式下可能会计算不准确。
  • HSM80:CYCLES_L2_PENDING 可能由于来自下一页预取器的请求而多计。

我认为您可以通过禁用 SMT(在 BIOS 中或使其他逻辑核心进入睡眠状态)来最大限度地减少 CYCLES_L2_PENDING 中的错误。另外,尽量不要触发NPP。这可以通过避免靠近虚拟页面末尾的位置来实现,其中下一页的翻译尚未在 TLB 层次结构中。

相关: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 发生在从(某些)其他线程(特别是在同一物理核心上)发出的负载上,而不仅仅是暂停的线程。 Erratum HSM146 提到当逻辑核心不在 C0 中时 CYCLES_LDM_PENDING 可能计数不准确,这解释了 CPU_CLK_UNHALTED.THREAD_P 如何可能小于 CYCLES_LDM_PENDING。尽管规范更新文档没有提供任何解决方法,但禁用 HT 可能会消除这种不准确性。

【讨论】:

  • 在 Skylake 上,计数器 CYCLE_ACTIVITY.CYCLES_L1D_PENDING 被重命名为 CYCLE_ACTIVITY.CYCLES_L1D_MISS(性能列表显示它是这样的)。同样在 event=0xA3,umask=0x2,cmask=0x2 的 Haswell CYCLE_ACTIVITY.CYCLES_LDM_PENDING 上。在 Skylake 上,同样的事件,umask,cmask 定义了CYCLE_ACTIVITY.CYCLES_L3_MISS,并且不再有CYCLE_ACTIVITY.CYCLES_LDM_PENDING,但是CYCLE_ACTIVITY.CYCLES_MEM_ANY 被添加为event=0xA3,umask=0x10,cmask=0x10
  • LDM 和 LDM_PENDING 到底是什么?
  • @BeeOnRope 代表负载依赖矩阵。
猜你喜欢
  • 2011-01-16
  • 1970-01-01
  • 2020-04-16
  • 2021-06-13
  • 2019-12-16
  • 1970-01-01
  • 2014-06-18
  • 2011-11-09
  • 2014-10-27
相关资源
最近更新 更多