14

英特尔 PMU 能否用于测量每核读/写内存带宽使用情况?这里的“内存”是指 DRAM(即,不命中任何缓存级别)。

4

5 回答 5

5

是的(ish),间接的。您可以使用计数器之间的关系(包括时间戳)来推断其他数字。例如,如果您对 1 秒的间隔进行采样,并且有 N 个最后一级 (3) 缓存未命中,则您可以非常确信每秒占用了 N*CacheLineSize 个字节。

将其准确地与程序活动相关联会变得有点棘手,因为这些未命中可能反映了 cpu 预取、中断活动等。

还有一个“除非此配置位处于此状态,否则此 cpu 不算数(MMX,SSE,AVX,..)”的泥潭;因此自己滚动很麻烦....

于 2017-12-14T14:45:22.423 回答
5

核心外响应性能监控工具可用于计算IDI 上来自特定核心的所有核心发起请求。请求类型字段可用于统计特定类型的请求,例如需求数据读取。然而,为了测量每核内存带宽,请求的数量必须以某种方式转换为每秒字节数。大多数请求具有高速缓存行大小,即 64 字节。其他请求的大小可能未知,并且可能会向内存带宽添加小于或大于高速缓存行大小的字节数。其中包括高速缓存行分割锁定请求、WC 请求、UC 请求和 I/O 请求(但这些不会增加内存带宽),以及需要完成所有挂起写入的围栏请求MFENCESFENCE和序列化指令)。

如果您只对可缓存带宽感兴趣,那么您可以计算可缓存请求的数量并将其乘以 64 字节。这可能非常准确,假设可缓存的高速缓存行拆分锁定请求很少见。不幸的是,从 L3(或 L4,如果可用)到内存的回写不能被当前任何微架构上的核心响应设施计算。原因是这些写回不是源自核心,通常是由于 L3 中的冲突未命中而发生的。因此,可以计算在 L3 中丢失并导致回写的请求,但核心外响应工具无法让您确定对 L3(或 L4)的任何请求是否导致回写。这就是为什么不可能“按核心”计算回写到内存的原因。

此外,核心外响应事件需要一个可编程的性能计数器,该计数器是 0、1、2 或 3 之一(但在禁用 hyptherhtreading 时不是 4-7)。

英特尔至强 Broadwell 支持许多资源控制器技术 (RDT) 功能。特别是,它支持内存带宽监控(MBM),这是准确测量每个内核的内存带宽的唯一方法。

MBM 与非核心响应相比具有三个优势:

  • 它使您能够测量一个或多个使用资源 ID 标识的任务的带宽,而不仅仅是每个内核。
  • 它不需要通用可编程性能计数器之一。
  • 它可以准确测量本地或总带宽,包括回写到内存。

非核心响应的优点是它支持请求类型、供应商类型和窥探信息字段。

Linux 从内核版本 4.6开始支持 MBM 。在 4.6 到 4.13 上,MBM 事件支持perf使用以下事件名称:

intel_cqm_llc/local_bytes - bytes sent through local socket memory controller
intel_cqm_llc/total_bytes - total L3 external bytes sent

也可以通过编程方式访问这些事件。

4.14开始,Linux 中 RDT 的实现发生了显着变化

在运行内核版本 4.16 的 BDW-E5(双套接字)系统上,我可以使用以下命令序列查看 MBM 的字节数:

// Mount the resctrl filesystem.
mount -t resctrl resctrl -o mba_MBps /sys/fs/resctrl

// Print the number of local bytes on the first socket.
cat /sys/fs/resctrl/mon_data/mon_L3_00/mbm_local_bytes

// Print the number of total bytes on the first socket.
cat /sys/fs/resctrl/mon_data/mon_L3_00/mbm_total_bytes

// Print the number of local bytes on the second socket.
cat /sys/fs/resctrl/mon_data/mon_L3_01/mbm_local_bytes

// Print the number of total bytes on the second socket.
cat /sys/fs/resctrl/mon_data/mon_L3_01/mbm_total_bytes

我的理解是自系统重置后计算字节数。

请注意,默认情况下,被监视的资源是整个套接字。

不幸的是,包括 MBM 在内的大多数 RDT 功能在支持它的 Skylake 处理器上都存在缺陷。根据SKZ4SKX4

英特尔® 资源控制器技术 (RDT) 内存带宽监控 (MBM) 不计算本地内存的可缓存回写流量。这会导致 RDT MBM 功能计算消耗的总带宽不足。

这就是为什么在 Linux 上运行 Skylake-X 和 Skylake-SP(它们是唯一支持 MBM 的 Skylake 处理器)时默认禁用它的原因。您可以通过将以下参数 rdt=mbmtotal,mbmlocal添加到内核命令行来启用 MBM。某些寄存器中没有启用或禁用 MBM 或任何其他 RDT 功能的标志。相反,这是在内核中的某些数据结构中跟踪的。

在 Intel Core 2 微架构上,可以使用此处BUS_TRANS_MEM讨论的事件来测量每个内核的内存带宽。

于 2019-04-06T22:23:23.987 回答
5

是的,这是可能的,尽管它不一定像编程通常的 PMU 计数器那样简单。

一种方法是使用通过 PCI 空间访问的可编程存储器控制器计数器。一个好的起点是pcm-memorypcm-memory.cpp中检查英特尔自己的实现。这个应用程序向您展示了每个插槽或每个内存控制器的吞吐量,这适用于某些用途。特别是,带宽在所有内核之间共享,因此在安静的机器上,您可以假设大部分带宽与被测进程相关联,或者如果您想在套接字级别进行监控,这正是您想要的。

另一种选择是使用“offcore repsonse”计数器的仔细编程。据我所知,这些与 L2(最后一个核心私有缓存)和系统其余部分之间的流量有关。您可以按核心响应的结果进行过滤,因此您可以使用各种“L3 未命中”事件的组合并乘以高速缓存行大小来获得读取和写入带宽。这些事件的粒度非常细,因此您可以通过首先导致访问的原因进一步分解它:指令获取、数据需求请求、预取等。

非核心响应计数器通常落后于工具等工具的支持perflikwid但至少最近的版本似乎有合理的支持,即使对于像 SKL 这样的客户端部件也是如此。

于 2017-12-14T18:15:33.240 回答
1

在某些架构上,perf您可以访问内存控制器的非核心 PMU 计数器。

$ perf list
[...]
uncore_imc_0/cas_count_read/                       [Kernel PMU event]
uncore_imc_0/cas_count_write/                      [Kernel PMU event]
uncore_imc_0/clockticks/                           [Kernel PMU event]
[...]

然后:

$ perf -e "uncore_imc_0/cas_count_read/,uncore_imc_0/cas_count_write/" <program> <arguments>

将报告从内存控制器#0 的读取和写入操作中从主内存传输到缓存的字节数。将该数字除以使用的时间,就可以得到所使用的平均内存带宽的近似值。

于 2021-04-30T09:24:17.743 回答
-2

我不确定英特尔 PMU,但我认为您可以使用英特尔 VTune 放大器(https://software.intel.com/en-us/intel-vtune-amplifier-xe)。这个有很多性能监控工具(内存、cpu缓存、cpu)。也许这对你有用。

于 2017-12-13T07:02:45.953 回答