PERF STAT 不计算内存加载但计算内存存储

PERF STAT does not count memory-loads but counts memory-stores

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

Ubuntu : 17.04

我一直在尝试使用 perf stat 收集内存访问的统计信息。我能够 收集内存存储的统计数据,但内存加载的计数 return 我的值为 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

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

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

为了收集内存加载事件,我不得不使用数字事件值。我基本上 运行 下面的命令 -

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

这里的 r81d0 表示用于计数的原始事件 "memory loads amongst all instructions retired"。 "u"可以理解为代表user-space.

另一方面,下面的命令

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

有 "r82d0:u" 作为代表 "memory stores amongst all instructions retired in userspace" 的原始事件。

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

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

When a user elects to sample one of these events, special hardware is used that can keep track of a data load from issue to completion. This is more complicated than simply counting instances of an event (as with normal event-based sampling), and so only some loads are tracked. Loads are randomly chosen, the latency determined for each, and the correct event(s) incremented (latency >4, >8, >16, etc). Due to the nature of the sampling for this event, only a small percentage of an application's data loads can be tracked at any one time.

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

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

实现了它的目的

如果你想计算退役的负载微指令总数,那么你应该使用 L1-dcache-loads,它映射到英特尔处理器上的 MEM_UOPS_RETIRED.ALL_LOADS 性能事件。

另一方面,mem-storesL1-dcache-stores 映射到所有当前 Intel 处理器上的完全相同的性能事件,即 MEM_UOPS_RETIRED.ALL_STORES,它计算所有退役的存储 uops .

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