是否可以使用英特尔PMU来测量每核读/写内存带宽的使用情况?这里“存储器”意味着DRAM(即,不在任何高速缓存级别中命中)。
答案 0 :(得分:5)
是(ish),间接地。您可以使用计数器之间的关系(包括时间戳)来推断其他数字。例如,如果您采样1秒间隔,并且有N个最后一级(3)缓存未命中,则您可以非常自信地每秒占用N * CacheLineSize字节。
将它准确地与程序活动联系起来有点棘手,因为这些未命中可能反映了cpu预取,中断活动等。
除非此配置位处于此状态,否则还有一个'此cpu不计数(MMX,SSE,AVX,...)的混乱“;因此滚动你自己是麻烦的....
答案 1 :(得分:3)
是的,这是可能的,虽然它不一定像编程通常的PMU计数器那样简单。
一种方法是使用可通过PCI空间访问的可编程存储器控制器计数器。一个好的开始是在pcm-memory
pcm-memory.cpp检查英特尔自己的实施。此应用程序显示每插槽或每内存控制器吞吐量,适用于某些用途。特别是,带宽在所有内核之间共享,因此在安静的机器上,您可以假设大部分带宽与被测流程相关联,或者如果您想在套接字级别进行监控,那么它就是您想要的
另一种选择是使用" offcore repsonse"计数器。据我所知,这些与L2(最后一个核心 - 私有缓存)和系统其余部分之间的流量有关。您可以根据offcore响应的结果进行过滤,这样您就可以结合使用各种" L3 miss"事件并乘以高速缓存行大小以获得读写带宽。这些事件非常精细,因此您可以通过首先导致访问的内容进一步细分:指令获取,数据需求请求,预取等等。
offcore响应计数器通常落后于perf
和likwid
等工具的支持,但至少最新版本似乎有合理的支持,即使对于像SKL这样的客户端部分也是如此。
答案 2 :(得分:2)
脱机响应性能监视工具可用于计算来自特定核心的IDI上所有源自核心的请求。请求类型字段可用于计算特定类型的请求,例如需求数据读取。但是,为了测量每核内存带宽,必须将请求数转换为每秒字节数。大多数请求具有高速缓存行大小,即64个字节。其他请求的大小可能是未知的,并且可能将小于或大于缓存行大小的字节数添加到内存带宽。其中包括缓存行拆分锁定请求,WC请求,UC请求和I / O请求(但这些请求不会增加内存带宽),以及需要完成所有未决写操作的篱笆请求(MFENCE
, SFENCE
,以及序列化说明)。
如果仅对可缓存带宽感兴趣,则可以计算可缓存请求的数量并将其乘以64字节。假设很少有可缓存的高速缓存行拆分锁定请求,这可能非常准确。不幸的是,当前任何微体系结构上的脱机响应功能都无法计算从L3(或L4,如果可用)到内存的写回。这样做的原因是这些回写不是源自核心的,通常是由于L3中的冲突未命中而导致的。因此,可以对L3中未命中并引起回写的请求进行计数,但是脱机响应工具无法使您确定对L3(或L4)的任何请求是否引起了回写。这就是为什么不可能“每个内核”计算回写到内存的原因。
此外,脱核响应事件需要一个可编程的性能计数器,该计数器可以是0、1、2或3(但在禁用超读功能时不是4-7)之一。
Intel Xeon Broadwell支持许多Resource Director Technology(RDT)功能。特别是,它支持Memory Bandwidth Monitoring(MBM),这是通常精确地测量每个内核的内存带宽的唯一方法。
MBM与脱机响应相比具有三个优势:
脱机响应的优点在于它支持请求类型,供应商类型和侦听信息字段。
Linux支持从kernel version 4.6开始的MBM。在4.6至4.13上,perf
使用以下事件名称支持MBM事件:
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的实现是significantly changed。
在运行内核版本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处理器上竟然是buggy。根据{{3}}和SKZ4:
英特尔®资源导向器技术(RDT)内存带宽监控 (MBM)不计算到本地的可缓存回写流量 记忆。这导致RDT MBM功能无法计算总数 消耗的带宽。
这就是为什么在Linux上在Skylake上运行时默认为SKX4的原因:\
答案 3 :(得分: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 读取和写入操作中从主内存传输到缓存的字节数。将该数字除以使用的时间,您就可以得到所使用的平均内存带宽的近似值。
答案 4 :(得分:-2)
我不确定英特尔PMU,但我认为您可以使用英特尔VTune放大器(https://software.intel.com/en-us/intel-vtune-amplifier-xe)。这个有很多性能监控工具(内存,cpu缓存,cpu)。也许这对你有用。