如何使用 Rocket Lake 通过 perf 访问 RAPL?

how to access RAPL via perf with Rocket Lake?

我有一个 Rocket Lake CPU(11900K),但是 perf 还不支持访问电源事件,我该怎么做?

性能事件列表:

pastebin.com + tcsSdxUx

我的 OS: Ubuntu 20.10 内核 5.12-RC6 性能版本:5.12-RC6

我可以用rapl-read.c读取Rapl值(link:http://web.eece.maine.edu/~vweaver/projects/rapl/

但是 rapl-read.c 不能用来分析 运行ing 程序。我希望对 运行ing 程序进行分析,不仅可以分析电源事件,还可以分析循环、分支等,Intel 的 SoCwatch 不能做这么多事情。

有什么方法可以将 Rocket Lake 电源事件支持添加到 perf 吗?我不知道原始电源事件计数器。

更新#1:

uname -a 输出:

Linux u128 5.12.0-051200rc6-generic #202104042231 SMP Sun Apr 4 22:33:57 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

更新#2: rapl-read -m输出

RAPL read -- use -s for sysfs, -p for perf_event, -m for msr

找到 RocketLake 处理器类型 0 (0), 1 (0), 2 (0), 3 (0), 4 (0), 5 (0), 6 (0), 7 (0)

    Detected 8 cores in 1 packages

正在尝试 /dev/msr 界面收集结果

    Listing paramaters for package #0
            Power units = 0.125W
            CPU Energy units = 0.00006104J
            DRAM Energy units = 0.00006104J
            Time units = 0.00097656s

            Package thermal spec: 125.000W
            Package minimum power: 0.000W
            Package maximum power: 0.000W
            Package maximum time window: 0.000000s
            Package power limits are unlocked
            Package power limit #1: 4095.875W for 0.108398s (enabled, not_clamped)
            Package power limit #2: 4095.875W for 0.032227s (disabled, not_clamped)
    PowerPlane1 (on-core GPU if avail) 0 policy: 16


    Sleeping 1 second

    Package 0:
            Package energy: 62.846985J
            PowerPlane0 (cores): 45.371277J
            PowerPlane1 (on-core GPU if avail): 0.000000 J
            DRAM: 0.000000J
            PSYS: -0.000000J

注意:能量测量值可能会在 60 秒左右溢出 所以尝试更频繁地对计数器进行采样。

更新 #3: 我发现很难简单地使用 rapl msr 来获得整个功耗:

ujtoj=1000000;
bgn_energy=$(rdmsr -d 0x611);
time sh doit.sh;
end_energy=$(rdmsr -d 0x611);
printf '%.3f\n' "$(((end_energy - bgn_energy)/ujtoj))e-3"

输出:

real    2m58.411s
user    2m58.068s
sys     0m0.168s
0.197

doit.sh 是运行 SPEC CPU2017 500.perlbench 测试的shell 脚本。对于 Zen 3,perf stat 输出的能量消耗(power/energy_pkg)约为 7486.61J,远高于简单使用 rdmsr 输出的“0.197”。

更新#4: 现在我找到了另一种方法来解决我的问题。 通过添加一些“#define”和“case:”代码很容易添加 RKL 支持。

--------------------------------------------------------------------------------
CPU name:   11th Gen Intel(R) Core(TM) i9-11900K @ 3.50GHz
CPU type:   Intel Rocketlake processor
CPU clock:  3.50 GHz
--------------------------------------------------------------------------------
Group 1: ENERGY
+-----------------------+---------+--------------+
|         Event         | Counter |  HWThread 6  |
+-----------------------+---------+--------------+
|   INSTR_RETIRED_ANY   |  FIXC0  | 996795747147 |
| CPU_CLK_UNHALTED_CORE |  FIXC1  | 321084408076 |
|  CPU_CLK_UNHALTED_REF |  FIXC2  | 216809163858 |
|       TEMP_CORE       |   TMP0  |           65 |
|     PWR_PKG_ENERGY    |   PWR0  |    4050.2952 |
|     PWR_PP0_ENERGY    |   PWR1  |    2982.4675 |
|    PWR_DRAM_ENERGY    |   PWR3  |            0 |
+-----------------------+---------+--------------+
+----------------------+------------+
|        Metric        | HWThread 6 |
+----------------------+------------+
|  Runtime (RDTSC) [s] |    62.0025 |
| Runtime unhalted [s] |    91.6329 |
|      Clock [MHz]     |  5189.3093 |
|          CPI         |     0.3221 |
|    Temperature [C]   |         65 |
|      Energy [J]      |  4050.2952 |
|       Power [W]      |    65.3247 |
|    Energy PP0 [J]    |  2982.4675 |
|     Power PP0 [W]    |    48.1024 |
|    Energy DRAM [J]   |          0 |
|    Power DRAM [W]    |          0 |
+----------------------+------------+

虽然在 v5.11-rc1 中添加了 RKL 核心和非核心性能事件,并且在 v5.9-rc5 中添加了基于 RAPL 的 powercap 支持,但尚不支持 RAPL perf PMU,甚至在最新的 5.15.1 内核版本。 TGL、TNT 和 LKF 也不支持 RAPL PMU。这对我来说很奇怪,因为似乎已经支持 ADL 和 SPR RAPL PMU。他们是不是忘了添加对这些其他处理器的支持?反正你暂时还得用别的工具。

请注意,对于核心 PMU 事件,perf_event 子系统仅允许您在 运行ning 在不受支持的处理器模型上时使用体系结构事件。但是您仍然可以使用 perf 手册页中记录的原始事件编码。此方法仅对没有约束的事件可靠,因为 perf_event 不知道不受支持的模型上可能存在的任何约束。大多数事件没有约束,所以这不是主要问题。

我不知道您为什么认为 rapl-read 不能用于分析程序。没有特定于程序或特定于核心的 RAPL 域。您可以 运行 rapl-read-m 选项直接访问 MSR 以获取能量读数,然后是您的程序,然后再次 运行 rapl-read。两个读数之间的差异为您提供了每个受支持域的能耗。请注意,您必须修改 rapl_msr() 函数,以便它在读数之间调用您的程序,而不是仅仅执行 sleep(1)。否则,它只会在大约一秒钟内报告能耗,与您的程序的能耗几乎没有任何关联。

rapl-read 目前不支持 RKL(或任何最新的 Intel 处理器)。但是您可以轻松添加 RAPL 支持,方法是首先从 cat /proc/cpuinfo 确定 CPU 模型,然后添加与当前支持的模型类似的 #define CPU_ROCKETLAKE model 之类的宏定义。我在 CPU 模式下只看到两个 switch 语句,一个在 detect_cpu(void) 中,一个在 rapl_msr(int core, int cpu_model) 中。只需为 CPU_ROCKETLAKE 添加一个案例。 RKL 与 SKL 具有相同的 RAPL 域,因此在两个函数中与 CPU_SKYLAKE 放在一起。应该这样做。或者您可以完全避免使用 rapl-read,只在 shell 脚本中使用 wrmsrrdmsr,该脚本读取数据,运行 程序,然后再次读取数据.

MSR 0x611 是 MSR_PKG_ENERGY_STATUS,它报告一个 32 位无符号值。该值的单位为MSR_RAPL_POWER_UNIT,默认为15.26uj。您似乎认为它是微焦耳。你确定MSR_RAPL_POWER_UNIT是这么说的吗?即便如此,表达式 $(((end_energy - bgn_energy)/ujtoj))e-3 的结果以千焦耳为单位,那么您如何将其与 Zen3 上的 power/energy_pkg 进行比较,后者显然以焦耳为单位?

如果正确的单位是 15.26uj,那么在英特尔处理器上的测量值就是 15.26*197000000 = 3,009,226,220,000 焦耳(约 3000 千兆焦耳)。但由于只有 MSR 寄存器的最低 32 位有效,因此最大值为 15.26*(2^32 - 1) = 65,541,200,921.7 焦耳(约 65 千兆焦耳)。所以我觉得单位不是15.26uj.

使用 test 输入的 500.perlbench 基准测试似乎需要大约 3 分钟才能完成。很难知道 MSR_PKG_ENERGY_STATUS 是否回绕了,因为报告的数字不是负数。

我认为最好在一个内核上 运行 500.perlbench,然后在另一个内核上 运行 每隔几秒读取一次 MSR_PKG_ENERGY_STATUS 的脚本。例如,您可以将 rdmsr -d 0x611 放入循环中,并在每次迭代中休眠一定秒数。由于 500.perlbench 需要相对较长的时间才能完成,因此您不必同时启动两个程序。通过这种方式,如果英特尔平台上的内核支持事件 power/energy-pkg/,您将模仿 perf stat -a -I 1000 -e power/energy-pkg/ 的工作方式。

我在 上讨论了英特尔基于 RAPL 的能量测量的可靠性。不过不知道有没有人验证过AMD的RAPL的准确性。我不清楚英特尔的 MSR_PKG_ENERGY_STATUS 和 AMD 的 Core::X86::Msr::PKG_ENERGY_STAT 之间的比较在多大程度上有意义。