【问题标题】:Read PMU counters in ARMv8 with Linux使用 Linux 读取 ARMv8 中的 PMU 计数器
【发布时间】:2018-08-02 05:38:03
【问题描述】:

我有一个带有 Linux 的 Raspberry Pi 3。 RPi3 有一个四核 cortex-A53,带有一个性能监控单元 (PMU) v3。我执行循环测试程序来做一些实时测试。 Cyclcitest 是一种应用程序,您可以在其中设置周期和迭代次数并计算延迟。因此,它会执行一些执行,并在进入睡眠状态之后直到下一个周期,系统将其唤醒。

我想在每次循环测试执行时读取缓存内存值,看看它在执行时有多少缓存未命中(我不希望任务处于睡眠状态时出现未命中)。

我已尝试执行 perf stat:

perf stat -o result1.txt -r 10 -i -e armv8_pmuv3/l1d_cache/ 
    -e armv8_pmuv3/l1d_cache_refill/ 
    -e armv8_pmuv3/l1d_cache_wb/ 
    -e armv8_pmuv3/l1d_tlb_refill/ 
    -e armv8_pmuv3/l1i_cache/ 
    -e armv8_pmuv3/l1i_cache_refill/ 
    -e armv8_pmuv3/l1i_tlb_refill/ 
    -e armv8_pmuv3/l2d_cache/ 
    -e armv8_pmuv3/l2d_cache_refill/ 
    -e armv8_pmuv3/l2d_cache_wb/ 
    -e armv8_pmuv3/mem_access/ 
    cyclictest -l57600 -m -n -t1 -p80 -i50000 -h300 -q --histfile=666_data_50

但是,它确实提供了大约 50% 的执行信息:

Performance counter stats for 'cyclictest -l57600 -m -n -t1 -p80 -i50000 -h300 -q --histfile=666_data_50' (10 runs):

     937729229      armv8_pmuv3/l1d_cache/                                        ( +-  2.41% )  (54.50%)
      44736600      armv8_pmuv3/l1d_cache_refill/                                     ( +-  2.33% )  (54.39%)
      44784430      armv8_pmuv3/l1d_cache_wb/                                     ( +-  2.11% )  (54.33%)
        294033      armv8_pmuv3/l1d_tlb_refill/                                     ( +- 13.82% )  (54.21%)
    1924752301      armv8_pmuv3/l1i_cache/                                        ( +-  2.37% )  (54.41%)
     120581610      armv8_pmuv3/l1i_cache_refill/                                     ( +-  2.41% )  (54.46%)
        761651      armv8_pmuv3/l1i_tlb_refill/                                     ( +-  4.87% )  (54.70%)
     215103404      armv8_pmuv3/l2d_cache/                                        ( +-  2.28% )  (54.69%)
      30884575      armv8_pmuv3/l2d_cache_refill/                                     ( +-  1.44% )  (54.83%)
      11424917      armv8_pmuv3/l2d_cache_wb/                                     ( +-  2.03% )  (54.76%)
     943041718      armv8_pmuv3/mem_access/                                       ( +-  2.41% )  (54.74%)

2904.940283006 seconds time elapsed                                          ( +-  0.07% )

不知道这个计数器是只统计这个任务运行的缓存信息,还是休眠的时候也统计。有人知道吗?我还有其他应用程序也在运行,它们可以按照我在 perf stat 中指定的那样修改这些计数器的值吗?

如果无法读取刚刚运行的任务所具有的计数器的确切值?使用模块或自定义用户空间应用程序?

谢谢!!

【问题讨论】:

  • 我认为 PMU 计数器是异常级别 1 (EL1) 或更高级别,因此您需要 root 权限才能执行此操作。似乎从任何类似控件的寄存器中引导 ARM 中任何有趣的东西都需要 EL1 或更高版本。您甚至无法阅读基本的机器功能,例如机器是否有可选的 CRC 和 Crypto 指令可用。
  • @jww: Linux perf 已经在内核模式下完成了所有的性能计数器访问。它虚拟化了硬件计数器,因此当您像这样使用perf stat 时,它们是每个进程的,没有-a 或其他一些系统范围的选项,这些选项会使计数器在其他任务运行时计数。 perf stat 使用这种方式只是计算您的进程,而不是当前 CPU 或其他内核正在执行的任何其他操作。
  • @PeterCordes 所以,如果我理解正确,我做得很好。但是,如果我执行两次,我会得到完全不同的值。此外,如果在一次测试中我设置了 50ms 的周期,而在另一次测试中设置了 100us,则第二个中 l1d_cache、l1i_cache 和 l2d_cache 的数量会更低。作为同一个应用,它不应该有相似的值吗?
  • 我认为你做得对,除非 ARM 上的 perf 与 x86 有很大不同。如果每单位时间的访问次数相似,让测试运行 50 ms 应该会产生比仅 100 us 更多的 L1D 访问。这是访问次数,而不是命中率。你没有说什么这个程序正在计算延迟。内存访问?还是别的什么?
  • 如果缓存在测试周期之间被其他工作污染(或者您在唤醒后被安排在不同的内核上),那么更短的周期将意味着更多的未命中/更低的吞吐量/更少的总访问次数.你的系统空闲吗?你看过 cpu-migrations perf 事件吗?您是否尝试使用 taskset -c 0 perf stat ... 将您的微基准测试固定到核心 0?

标签: linux caching arm counter perf


【解决方案1】:

每个性能监视器硬件都受到通道数量的限制:每个时刻可以同时计算多少个事件。例如,许多现代 x86/x86_64 可能每个 cpu 内核有 4 个灵活通道和 3 个固定通道。当您向分析器询问更多事件时,它将多路复用(如VTunePAPI 所做的那样)。当多路复用处于活动状态时,某些事件 e1 测量了 55% 的运行时间,并且 perf stat(但不是 perf record?)will extrapolate counts into full running time(“C. Multiplexing”)。这个推断可能有一些错误。

带有 PMU v3 的 cortex-A53 只有六个通道:http://infocenter.arm.com/help/topic/com.arm.doc.ddi0500d/BIIDADBH.html PMEVCNTR0_EL0 - PMEVCNTR5_EL0 和 PMEVTYPER0_EL0 - PMEVTYPER5_EL0。尝试使用不超过 6 个事件启动 perf stat 以关闭事件多路复用:

perf stat -o result1.txt -r 10 -i \
    -e armv8_pmuv3/l1d_cache/  \
    -e armv8_pmuv3/l1d_cache_refill/  \
    -e armv8_pmuv3/l1d_cache_wb/  \
    -e armv8_pmuv3/l1d_tlb_refill/  \
    -e armv8_pmuv3/l1i_cache/  \
    -e armv8_pmuv3/l1i_cache_refill/  \
    cyclictest -l57600 -m -n -t1 -p80 -i50000 -h300 -q --histfile=666_data_50

perf stat -o result2.txt -r 10 -i \
    -e armv8_pmuv3/l1i_tlb_refill/  \
    -e armv8_pmuv3/l2d_cache/  \
    -e armv8_pmuv3/l2d_cache_refill/  \
    -e armv8_pmuv3/l2d_cache_wb/  \
    -e armv8_pmuv3/mem_access/  \
    cyclictest -l57600 -m -n -t1 -p80 -i50000 -h300 -q --histfile=666_data_50

您也可以尝试将事件分组到集合中:-e \{event1,event2...,event6\} (https://stackoverflow.com/a/48448876) 并且集合将与其他集合复用。

【讨论】:

    猜你喜欢
    • 2020-05-21
    • 1970-01-01
    • 2020-02-23
    • 1970-01-01
    • 2021-11-22
    • 2018-01-26
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    相关资源
    最近更新 更多