PERF 统计不计算内存负载,但计算内存存储



Linux 内核:4.10.0-20-通用(也在 4.11.3 上尝试过)

乌班图 :17.04

我一直在尝试使用perf stat收集内存访问的统计信息。我能够收集内存存储的统计信息,但内存负载计数返回 0 值

以下是内存存储的详细信息:-

perf stat -e cpu/mem-stores/u ./libquantum_base.arnab 100
N = 100, 37 qubits required
Random seed: 33
Measured 3277 (0.200012), fractional approximation is 1/5.
Odd denominator, trying to expand by 2.
Possible period is 10.
100 = 4 * 25
Performance counter stats for './libquantum_base.arnab 100':
158,115,510      cpu/mem-stores/u                                            
0.559922797 seconds time elapsed

对于内存加载,我得到一个 0 计数,如下所示:-

perf stat -e cpu/mem-loads/u ./libquantum_base.arnab 100
N = 100, 37 qubits required
Random seed: 33
Measured 3277 (0.200012), fractional approximation is 1/5.
Odd denominator, trying to expand by 2.
Possible period is 10.
100 = 4 * 25
Performance counter stats for './libquantum_base.arnab 100':
0      cpu/mem-loads/u                                             
0.563806170 seconds time elapsed

我不明白为什么这不能正确计算。我应该以任何方式使用不同的事件来获取正确的数据吗?

mem-loads事件映射到英特尔处理器上的MEM_TRANS_RETIRED.LOAD_LATENCY_GT_3性能监视单元事件。事件MEM_TRANS_RETIRED.LOAD_LATENCY_*是特殊的,只能通过使用p修饰符进行计数。也就是说,您必须指定要执行的mem-loads:p才能正确使用该事件。

MEM_TRANS_RETIRED.LOAD_LATENCY_*是一个精确的事件,只有在精确的级别上计数才有意义。根据这篇英特尔文章(强调我的):

当用户选择对其中一个事件进行采样时,特殊硬件是 用于跟踪从发出到完成的数据加载。 这比简单地计算事件的实例更复杂 (与正常的基于事件的采样一样),因此只有一些负载是 跟踪。负载是随机选择的,为每个负载确定延迟, 以及增加的正确事件(延迟>4、>8、>16 等)。 由于 对于本次事件的抽样性质,只有一小部分 的 应用程序的数据加载可以在任何时候进行跟踪

如您所见,MEM_TRANS_RETIRED.LOAD_LATENCY_*绝不计算负载总数,它根本不是为此目的而设计的。

如果要确定代码中的哪些指令发出的加载请求需要超过特定周期数才能完成,则MEM_TRANS_RETIRED.LOAD_LATENCY_*是要使用的正确性能事件。事实上,这正是perf-mem的目的,它通过使用这个事件来实现它的目的。

如果要计算停用的负载 uop 总数,则应使用L1-dcache-loads,它映射到英特尔处理器上的MEM_UOPS_RETIRED.ALL_LOADS性能事件。

另一方面,mem-storesL1-dcache-stores映射到当前所有英特尔处理器上完全相同的性能事件,即MEM_UOPS_RETIRED.ALL_STORES,它确实计算所有已停用的存储 uops。

因此,总而言之,如果您使用的是perf-stat,您应该(几乎)始终使用L1-dcache-loadsL1-dcache-stores分别计算退役负载和存储。这些映射到您在发布的答案中使用的原始事件,只是更便携,因为它们也适用于 AMD 处理器。

我使用Broadwell(CPU e5-2620)服务器机器来收集以下所有事件。

为了收集内存加载事件,我必须使用数字事件值。我基本上运行了以下命令 -

./perf record -e "r81d0:u" -c 1 -d -m 128 ../../.././libquantum_base 20

此处 r81d0 表示用于计数"所有停用指令中的内存负载"的原始事件。可以理解为"u"表示用户空间。

另一方面,以下命令,

./perf record -e "r82d0:u" -c 1 -d -m 128 ../../.././libquantum_base 20

将"R82D0:U"作为原始事件,表示"用户空间中停用的所有指令中的内存存储"。

最新更新