PMU : TrustedFirmware运行时的性能数据的统计方法

电子说

1.3w人已加入

描述

思考: 如何统计Trustedfirmware的性能数据? tee的呢?uboot的呢?

如何统计cache命令率?

如何计算 IPC:Instructions Per Cycle?

Armv8-A CPU 中的性能监控单元 (PMU) 提供硬件级性能监控和分析功能。PMU 通过计数器收集硬件事件计数。计数器包括周期计数器和事件计数器。您可以配置:

*每个事件计数器对指定的硬件事件进行计数。
*每个计数器从各种 CPU 异常级别和状态的工作负载收集硬件事件。

perf 等工具使用 PMU 来分析在 Armv8-A CPU 上运行的 Linux 应用程序。然而,没有通用的方法来使用 PMU 来分析固件,因为它运行在裸机环境中。

要使用 PMU 分析固件,一种简单的方法是以库的形式添加 PMU 支持。在这篇博文中,我们提供了一个 PMU 库作为参考实现。该库已在基于Armv8.0-A CPU的平台上得到验证。我们还描述了如何在固件中添加 PMU 支持以及如何使用 PMU 分析固件。Trusted Firmware-A (TF-A) 和 U-Boot 用作示例固件。

下表列出了 PMU 库的组件

计数器

第 1 阶段: 向固件添加 PMU 支持

使用以下命令将PMU库的所有文件解压到固件 lib/pmu 中的 路径。 unzip armv8_pmuv3_library.zip-d ${FIRMWARE_PATH}/lib/pmu

根据您使用的固件,您需要对文件进行如下特定更改。Makefile

(1)、TF-A

Makefile 如下修改位于 TF-A 根路径中的现有文件。

1.BL_COMMON_SOURCES += lib/pmu/armv8_pmuv3_fn.c lib/pmu/armv8_pmuv3_events.c

2.INCLUDES += -Ilib/p

(2)、uboot

修改Makefile U-Boot 根路径下的现有文件,如下所示。

1.UBOOTINCLUDE += -Ilib/pmu

Makefile 在与 PMU 库相同的目录中创建一个文件。按如下方式填写文件。

1.obj-y += armv8_pmuv3_fn.o armv8_pmuv3_events.o

现在,您可以重建固件。如果构建成功,请进入第 2 阶段。

第 2 阶段:选择 PMU 事件进行分析

首先,获取运行固件的 Armv8-A CPU 的支持 PMU 事件。有关 PMU 事件,请参阅 CPU 技术参考手册 (TRM)。

jevents.py在 PMU 库中,您还可以使用按以下步骤命名的 Python 脚本。

(1)、获取指定CPU支持的PMU事件 GitHub Machine-readable data 维护每个 Arm CPU 支持的 PMU 事件。它采用JSON格式存储PMU事件的事件助记符、事件编号等信息。该信息与CPU TRM中的信息一致。

jevents.pyPMU 库中 命名的 Python 脚本克隆 Machine-readable data, 将 JSON 格式转换为 C 格式,并生成名为armv8pmuv3events.c. 您可以按如下方式使用它。

首先,使用以下命令列出所有支持转换的CPU名称。

python3 jevents.py--list然后,使用以下命令指定要转换的CPU的名称。该命令将生成名为armv8pmuv3events.c. 该文件包含两种类型的数组。一种是针对指定CPU的支持PMU事件。另一个是针对选定的 PMU 事件进行分析。 python3 jevents.py--cpu

armv8_pmuv3_events.c生成的文件示例 jevents.py 如下。我们将 cpu 名称指定为cortex-a53。名为的数组pmu_events_map包含 Cortex-A53 的所有支持 PMU 事件。这与 Cortex-A53 TRM 相同。您可以从此处选择 PMU 事件并将所选事件放入名为 的数组中evt_select。

计数器

(2)、选择 PMU 事件进行分析 在初始分析中,通常您需要选择各种 PMU 事件。这将使您全面了解要分析的代码。

对于 Armv8-A CPU,每个 CPU 的可用事件计数器是有限的。您可以参考 CPU TRM 以获取该编号。如果所需的 PMU 事件数量超过可用计数器,可以使用以下方法。

  • 将所有要选择的 PMU 事件分组。每组中的事件数量不得超过 PMU 的可用计数器。
  • 创建多个pmu_event_selected 结构数组并将每一组放入一个数组中。
  • 多次分析相同的代码,一次选择一个阵列,然后重复该过程,直到测量所有事件。

例如,我们 在.c文件中创建两个名为 和 的pmu_event_selected 结构体数组。对于 Cortex-A53,可使用 1 个周期计数器和 6 个事件计数器。每个数组中的 PMU 事件数量不超过此数量。此外,在每个阵列中,PMU 事件都是相关的,以确保分析数据具有可比性。

我们将这两个数组用于以下分析示例。

计数器

第 3 阶段: 使用 PMU 分析固件

现在,您可以使用 PMU 来分析固件。对要分析的固件中的特定代码使用以下过程。

  • 将开始分析点放在代码之前。这将配置、启用并读取每个 PMU 计数器的当前值作为预分析值。
  • 将停止分析点放置在代码后面。这将禁用每个 PMU 计数器值并将其读取为分析后值。
  • 重建固件并再次运行代码。计算每个 PMU 计数器的分析前值和分析后值之间的差异。这将收集统计分析结果。

在PMU库中,armv8pmuv3fn.c 提供了参考实现。

(1)、将分析点放置在固件中

您只需在要分析的代码之间添加两个名为pmuv3startProfiling 和的函数即可。pmuv3stopProfiling对于每个分析,传递一个pmueventselected 结构数组作为参数。

根据您想要分析的 PMU 事件数量,您需要分析一次或多次。以下是两个分析示例。

例一

要分析 TF-A 中的函数并重点关注缓存行为,您只能选择 为单个分析命名enablemmuel3 的数组 。evtselectcache

计数器

例二

要了解U-Boot 中的工作负载特征,您可以选择名为 和 的crc32 阵列 。这样,您需要对同一代码进行多次分析才能收集所有分析数据。evtselectcacheevtselectwlc

由于该domemcrc 函数是通过命令调用的,因此您可以对固件进行一次编程,然后通过多次输入相同的命令来重复分析。

计数器

(2)、了解 PMU 分析的实现

该函数startProfiling 执行以下操作。

  • 为 PMU 执行必要的初始化。它检查CPU PMU 支持的事件计数器数量是否适合所选事件。然后,它设置MDCREL2 或 MDCREL3 以在当前异常级别启用 PMU 分析。这是因为固件通常在 EL2/EL3 或安全状态下运行,其中禁止分析以防止信息泄漏。
  • 配置每个 PMU 计数器以分析当前异常级别和选定的 PMU 事件。
  • 启用每个 PMU 计数器。
  • 读取每个 PMU 计数器的当前值作为预分析值。

该函数stopProfiling 执行以下操作。

  • 禁用每个 PMU 计数器。
  • 读取每个 PMU 计数器的当前值作为分析后值。
  • 转储此分析的结果。
  • 对 PMU 执行必要的去初始化。这会禁用工作在 EL2/EL3 或安全状态的 PMU。

对于上一部分提到的示例,在 Juno r2 平台上执行分析。分析的输出如下。

例一

计数器

从输出中可以看到,它记录了此分析中每个选定 PMU 事件和周期的预分析和后分析值。此外,它还计算差异,并将它们记录在名为 的列中DELTA。

对于 Cortex-A53 CPU,PMU 事件L1DTLBREFILL 包含在 的计数中L1DCACHEREFILL。因此,您可能会发现 的计数值L1DCACHEREFILL 大于 的计数值L1D_CACHE。

示例二

计数器

正如您在上面看到的,cycles 两个分析会话的结果几乎相同。

从第一个分析结果中,您可以参考Arm架构参考手册来抽象出一些有意义的指标,如下所示。

计数器

根据第二个分析结果,您可以计算 Instructions Per Cycle (IPC) as follows.

IPC = INST_RETIRED / CYCLES

The IPC of this workload is 0.23. This is caused by many MEM_ACCESS operations. You might determine the workload as the computation-intensive one.

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分