如何使用 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 脚本中使用 wrmsr
和 rdmsr
,该脚本读取数据,运行 程序,然后再次读取数据.
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
之间的比较在多大程度上有意义。
我有一个 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 脚本中使用 wrmsr
和 rdmsr
,该脚本读取数据,运行 程序,然后再次读取数据.
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/
的工作方式。
我在 MSR_PKG_ENERGY_STATUS
和 AMD 的 Core::X86::Msr::PKG_ENERGY_STAT
之间的比较在多大程度上有意义。