DRAM 每列内存访问的性能计数器

Performance Counter for DRAM Per-Rank Memory Access

我有一个 Intel(R) Core(TM) i7-4720HQ CPU @ 2.60GHz (Haswell) 处理器。随着时间的推移,我需要检索每个 DRAM ranknumber 访问次数,以 估计 它的功率消耗。根据芯片组文档的第 261 页(即 Datasheet, volume 2 (M- and H-processor lines)),我可以使用寄存器 RAM—DRAM_ENERGY_STATUS 中的 32 位值作为 DRAM 能量 估计。但我需要 rank-level 能量估计。我还可以使用 coreoffcore DRAM 访问性能计数器来 estimate 功耗,但是,如前所述之前,我需要 per-rank 统计数据除此之外,他们报告整个系统统计数据,而能量是按等级计算的。他们还没有报告许多 DRAM 访问。

因此,IMC 计数器(即 uncore 计数器)应该是理想 的选择。 Perf 支持 per-rank 计数器。我尝试使用 PCM-Memory to access IMC counter information. But /sys/bus/event_source/devices/uncore_imc is not mounted by the kernel (the version is 5.0.0-37-generic) and the tool does not detect the CPU. I tried to access uncore performance counters, manually. Whole-system DRAM access counters are documented, here(它们 不是 记录在 上述 芯片组手册中。我可以使用这些计数器检索 total DRAM readwrite 访问。但是,关于 channelrank-level 访问统计信息,no 信息。我怎样才能找到与这些 counters 关联的 offset?我应该使用试错法吗?


P.S.: 这个问题也在 Intel Software Tuning, Performance Optimization & Platform Monitoring Forum.

被问到

MSR_DRAM_ENERGY_STATUS 始终报告所有内存通道的能量消耗估计值。没有简单的方法可以将其分解为每等级能量。该寄存器报告了对 Haswell 的高度准确估计。

5.0.0-37-generic内核是一个Ubuntu内核,支持Haswell上的uncore_imc/data_reads/uncore_imc/data_writes/事件,代表数据读取CAS命令和数据写入分别来自 IMC 的 CAS 命令。一个完整的缓存行读取和一个完整的缓存行写入事务会导致内存总线上的单个突发 64 字节事务到单个列。部分读取也作为总线上的单个全行读取执行,但由于协议的限制,部分写入可能需要先进行全行读取,然后再进行全行写入。部分写入通常可以忽略不计。

uncore_imc/data_reads/uncore_imc/data_writes/ 事件针对任何单元生成的 DRAM 内存请求发生,而不仅仅是内核。这些名称由 perf 给出,它们分别对应于 UNC_IMC_DRAM_DATA_READSUNC_IMC_DRAM_DATA_WRITES,您引用的英特尔文章中提到了它们。那里提到的其他三个事件允许您分别计算三个可能来源(GT、IA 和 IO)中每一个的请求(不是 CAS 命令!)。您不会在旧内核的 /sys/bus/event_source/devices/uncore_imc/events 下找到它们。从主流内核 v5.9-rc2 开始,perf 支持它们。

顺便说一下,PCM 也支持这些事件,它用于报告所有通道的读写带宽,但您应该使用工具 pcm.x,而不是 [=23] =],它只适用于服务器处理器。

Haswell H 处理器系列处理器有一个片上内存控制器和两个 DDR3L 64 位通道。每个通道可以包含零个、一个或两个 DIMM,所有通道的总容量高达 32 GB。此外,每个 DIMM 最多可以包含两个列,因此单个通道可以包含 0 到 4 个列之间的任何位置。 i7-4720HQ 是一款高端移动处理器。您可能使用的是 8 GB 或 16 GB 内存的笔记本电脑。如果内存拓扑自购买后未更改,它可能只有两个 4GB 或 8GB DIMM,每个通道一个,如果用户需要,每个通道剩余一个空闲插槽可用于扩展。这意味着每个通道有一个或两个等级。

根据物理地址如何映射到等级的知识,您可以估算出每个等级的访问次数。如果每个通道都装有相同容量的单列 DIMM,则处理器上的映射很简单。物理地址的第 6 位(即第 7 位)确定请求映射到哪个通道,从而确定哪个等级。您可以通过 运行 perf recordMEM_LOAD_UOPS_L3_MISS_RETIRED.LOCAL_DRAM 上使用 --phys-data 选项收集一组请求的物理地址样本。显然,这组样本可能仅代表到达 IMC 的核心发起的退役负载,它们是 IMC 上所有请求的一小部分。

在我看来,您想测量每个等级的内存访问次数,以便从总 DRAM 能量中估算每个等级的能量,但这一点都不简单,原因如下:

  • 并非所有 CAS 命令都具有相同的能量消耗。预充电和激活命令不会被任何事件计算在内,并且可能会消耗大量能量,尤其是在行缓冲区未命中率较高的情况下。
  • 即使IMC中的请求为零,只要至少有一个活跃的内核,内存通道就会供电并消耗能量。
  • 处理相同类型和相同地址的请求所花费的时间可能会有所不同,具体取决于周围的请求,这是由于等级到等级周转和读写切换所需的时间延迟。

尽管如此,我认为在给定对每个等级的请求数量的代表性估计(如上所述)的情况下,有可能建立一个良好的每个等级能量上限和下限模型。

最重要的是,没有简单的方法可以像在服务器处理器上那样获得按等级计数的奢侈。