DRAM 访问的性能计数器

Posted

技术标签:

【中文标题】DRAM 访问的性能计数器【英文标题】:Performance Counters for DRAM Accesses 【发布时间】:2021-02-26 20:44:04 【问题描述】:

我想在我的应用程序中检索 DRAM 访问次数。准确地说,我需要区分数据和代码访问。处理器是Intel(R) Core(TM) i7-4720HQ CPU @ 2.60GHz (Haswell)。基于Intel Software Developer's Manual, Volume 3 和Perf,我可以找到分类以下内存访问相关的事件:

(A)
LLC-load-misses                                    [Hardware cache event]
LLC-loads                                          [Hardware cache event]
LLC-store-misses                                   [Hardware cache event]
LLC-stores                                         [Hardware cache event]
=========================================================================
(B)
mem_load_uops_l3_miss_retired.local_dram          
mem_load_uops_retired.l3_miss  
=========================================================================
(C)
offcore_response.all_code_rd.l3_miss.any_response 
offcore_response.all_code_rd.l3_miss.local_dram   
offcore_response.all_data_rd.l3_miss.any_response 
offcore_response.all_data_rd.l3_miss.local_dram   
offcore_response.all_reads.l3_miss.any_response   
offcore_response.all_reads.l3_miss.local_dram     
offcore_response.all_requests.l3_miss.any_response
=========================================================================
(D)
offcore_response.all_rfo.l3_miss.any_response     
offcore_response.all_rfo.l3_miss.local_dram       
=========================================================================
(E)
offcore_response.demand_code_rd.l3_miss.any_response
offcore_response.demand_code_rd.l3_miss.local_dram
offcore_response.demand_data_rd.l3_miss.any_response
offcore_response.demand_data_rd.l3_miss.local_dram
offcore_response.demand_rfo.l3_miss.any_response  
offcore_response.demand_rfo.l3_miss.local_dram    
=========================================================================
(F)
offcore_response.pf_l2_code_rd.l3_miss.any_response
offcore_response.pf_l2_data_rd.l3_miss.any_response
offcore_response.pf_l2_rfo.l3_miss.any_response   
offcore_response.pf_l3_code_rd.l3_miss.any_response
offcore_response.pf_l3_data_rd.l3_miss.any_response
offcore_response.pf_l3_rfo.l3_miss.any_response

我的选择如下:

看来LLC-load-missesLLC-store-misses之和 将返回 whole DRAM 访问(等效地,我可以使用 LLC-missesPerf)。 对于仅数据访问,我使用了mem_load_uops_retired.l3_miss。 它不包括商店,但似乎OK因为商店似乎 很多 不那么频繁?!)。 简单地说,LLC-load-misses - mem_load_uops_retired.l3_miss = DRAM Accesses for Code(因为代码是只读)。

这些选择是否合理


我的其他问题:(第二个最重要)

什么是local_dramany_response? 起初,group (C) 似乎是 group 的 load 事件的更高分辨率版本(一)。但我的测试表明,组中的事件组中的事件更频繁。例如,在简单基准测试中,offcore_response.all_reads.l3_miss.any_response 事件的数量是LLC-load-misses两倍 组 (E),属于 demand reads(即所有 non-prefetched 读取)。这是否意味着,例如:offcore_response.all_data_rd.l3_miss.any_response - offcore_response.demand_data_rd.l3_miss.any_response = 预取导致的 DRAM 读取访问

组 (D),包括由Read for Ownership 操作(针对Cache Coherency 协议)引起的 DRAM 访问事件。这似乎与我的问题无关

组 (F),计算由 L2-cache prefetcher 引起的 DRAM 读取,这也与我的问题无关

【问题讨论】:

请注意,对同一缓存行的多次未命中(同时)只会触发一个 LLC-load-misses 事件,但 IIRC 每一个都将计为 mem_load_uops_retired.l3_miss。例如如果你访问一个结构的多个成员,这些成员都来自同一个缓存行,加载的微指令将自己附加到一个 LFB 以等待传入的缓存行。 @PeterCordes - 不,同一行的后续未命中应该是mem_load_uops_retired.hit_lfb “DRAM 访问”是指源自内核并在 L3 中丢失并进入 IMC 的访问?正在寻找适用于 i7-4720HQ 或更多处理器集合的解决方案? 是的,上面提到的处理器就足够了。 如果你没有像 @HadiBrais 这样 ping 我,我可能会忘记跟进你的回复。 【参考方案1】:

根据我对问题的理解,我建议在指定的处理器上使用以下两个事件:

OFFCORE_RESPONSE.ALL_READS.L3_MISS.LOCAL_DRAM:这包括所有可缓存的数据读写事务和所有代码获取事务,无论事务是由指令(退休与否)或预取或任何类型启动的。每个事件恰好代表对内存控制器的 64 字节读取请求。 OFFCORE_RESPONSE.ALL_CODE_RD.L3_MISS.LOCAL_DRAM:这包括对 IMC 的所有代码提取访问。

(我认为对于不可缓存的代码获取请求,这两个事件都不会发生,但我没有对此进行测试,文档对此并不清楚。)

“数据访问”可以与“代码访问”分开测量,方法是从第一个事件中减去第二个事件。这两个事件可以在 Haswell 上的同一个逻辑核心上同时计数,无需多路复用。

当然还有其他交易确实会进入 IMC,但不计入上述两个事件中的任何一个。其中包括:(1) L3 写回,(2) 来自内核的不可缓存的部分读写,(3) 完全 WCB 驱逐,以及 (4) 来自 IO 设备的内存访问。根据工作负载,类型 (1)、(3) 和 (4) 的访问可能构成对 IMC 的总访问的很大一部分。

似乎 LLC-load-misses 和 LLC-store-misses 的总和将 返回整个 DRAM 访问(等效地,我可以使用 LLC-misses 在性能中)。

注意以下几点:

事件LLC-load-misses 是一个映射到原生事件OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.ANY_RESPONSEperf 事件。 事件LLC-store-misses 映射到OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.ANY_RESPONSE

这些不是您想要的事件,因为:

ANY_RESPONSE 位表示事件可能发生在针对任何单元的请求,而不仅仅是 IMC。 这些事件计算 L1 数据预取和页面遍历请求,但不计算 L2 数据预取。您通常需要计算所有消耗内存带宽的预取。

对于仅数据访问,我使用了 mem_load_uops_retired.l3_miss。它确实 不包括商店,但似乎还可以(因为商店似乎很多 不那么频繁?!)。

在 Haswell 上使用 mem_load_uops_retired.l3_miss 存在许多问题:

在某些情况下,此事件不可靠,因此如果有替代方案,应避免此事件。否则,分析方法应考虑此事件计数的潜在不可靠性。 该事件仅针对来自已停用负载的请求发生,它会忽略推测性负载和所有存储,这可能很重要。 以有意义的方式对这些事件和其他事件进行算术运算并不容易。例如,您执行“LLC-load-misses - mem_load_uops_retired.l3_miss = DRAM Accesses for Code”的建议是不正确的。

local_dram 和 any_response 是什么?

并非所有在 L3 中遗漏的请求都会转到 IMC。一个典型的例子是内存映射的 IO 请求。你说你只想要去 IMC 的核心发起的请求,所以local_dram 是正确的位。

起初,组 (C) 似乎是更高分辨率的版本 组 (A) 的负载事件。但我的测试表明, 前一组比后者频繁得多。例如,在一个 简单的基准,数量 offcore_response.all_reads.l3_miss.any_response 事件是两倍 与 LLC-load-misses 一样多。

这是正常的,因为offcore_response.all_reads.l3_miss.any_response 包含LLC-load-misses 并且很容易变得更大。

组 (E),与请求读取(即所有非预取读取)有关。 这是否意味着,例如: offcore_response.all_data_rd.l3_miss.any_response - offcore_response.demand_data_rd.l3_miss.any_response = DRAM 读取 预取导致的访问?

不,因为:

any_response 位如上所述, 此减法仅导致 L2 数据加载预取,而不是所有数据加载硬件和软件预取。

【讨论】:

@TheAhmad 你没有提供足够的信息让我对此发表评论。这取决于代码和执行环境。如果对您很重要,您可以发布另一个问题。 @TheAhmad 我宁愿不去猜测所有细节。但是OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.ANY_RESPONSE 大很多是正常的。 @TheAhmad 当然。是什么让您认为它是在内核之间共享的? @TheAhmad 是的,这个事件在 Haswell 上按逻辑核心计算,没问题。 @TheAhmad OFFCORE_RESPONSE 事件不是非核心事件。前者在核心计数器上编程,而后者在非核心计数器上编程。非核心事件在标题为“非核心监控指南”之类的文档中进行了讨论。

以上是关于DRAM 访问的性能计数器的主要内容,如果未能解决你的问题,请参考以下文章

通过 WMI 访问应用程序的自定义性能计数器

使用 PowerShell 在远程计算机上启动监视应用程序时的性能计数器访问

如何在 w2k8 中使用性能计数器

C# 性能计数器帮助,Nvidia GPU

windows下使用性能计数器遇到的坑

我将性能计数器的值发送到 Graphite 的方法非常慢。瓶颈是啥?以及如何改进?