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

时间:2017-06-09 21:07:17

标签: linux x86 intel perf

Linux内核: 4.10.0-20-generic(也在4.11.3上试过)

Ubuntu: 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

我无法理解为什么这不恰当。 我应该以任何方式使用其他事件来获取正确的数据吗?

2 个答案:

答案 0 :(得分:3)

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

MEM_TRANS_RETIRED.LOAD_LATENCY_*是一个精确的事件,只有在精确的级别进行计数才有意义。根据{{​​3}}英特尔文章(重点是我):

  

当用户选择对这些事件之一进行采样时,将使用特殊的硬件   可以跟踪从发布到完成的数据加载。   这比简单地计算事件实例要复杂得多   (与基于事件的常规采样一样),因此仅某些负载   跟踪。随机选择负载,为每个负载确定延迟,   并且正确的事件会增加(延迟> 4,> 8,> 16等)。到期   根据这次活动的抽样性质,只有一小部分   可以随时跟踪应用程序的数据负载

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

如果您要确定代码中的哪些指令正在发出需要完成多个周期的负载请求,那么MEM_TRANS_RETIRED.LOAD_LATENCY_*是正确的性能事件。实际上,这正是perf-mem的目的,并且通过this达到了目的。

如果要计算已退休的负载总数,则应使用L1-dcache-loads,它映射到Intel处理器上的MEM_UOPS_RETIRED.ALL_LOADS性能事件。

另一方面,mem-storesL1-dcache-stores映射到所有当前Intel处理器(即MEM_UOPS_RETIRED.ALL_STORES)上完全相同的性能事件,该事件不计算所有已退休的存储单元。 / p>

因此,总而言之,如果您使用的是perf-stat,则应该(几乎)始终使用L1-dcache-loadsL1-dcache-stores分别计算退休的货物和仓库。这些事件映射到您在发布的答案中使用的原始事件,但它们也可在AMD处理器上使用,因此更便于移植。

答案 1 :(得分:1)

我使用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”作为原始事件,表示“在用户空间中退役的所有指令中的内存存储”。