问题描述
我有一个 Rocket Lake cpu(11900K),但是 perf 还不支持它的访问电源事件,我该怎么做?
性能事件列表:
pastebin.com + tcsSdxUx
我的操作系统:Ubuntu 20.10 内核 5.12-RC6 性能版本:5.12-RC6
我可以使用 rapl-read.c 读取 Rapl 值(链接:http://web.eece.maine.edu/~vweaver/projects/rapl/)
但是 rapl-read.c 不能用来分析正在运行的程序。我希望对正在运行的程序做性能分析,不仅是电源事件,还有周期、分支等,Intel 的 SoCwatch 做不了这么多。
有什么方法可以为 perf 添加 Rocket Lake 电源事件支持吗?我不知道原始电源事件计数器。
更新 #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.9-rc5 中添加了 intel_rapl 驱动程序中对 RKL 的支持,在 v5.11-rc1 中添加了 core 和 uncore perf 事件。你确定你有 v5.12-rc6 吗? uname -a
打印什么? Ubuntu 20.10 基于 v5.8 和其他向后移植的补丁(其中一个补丁支持现代英特尔客户端处理器上可用的所有 uncore_imc
事件)。
如果 perf_event 子系统在不受支持的处理器模型上运行,您可以仅使用架构事件。但是您仍然可以使用 perf 手册页中记录的原始事件编码。这种方法只对没有约束的事件可靠,因为 perf_event
不知道不受支持的模型上可能存在的任何约束。大多数事件没有限制,所以这不是一个大问题。
我不知道您为什么认为 rapl-read
不能用于分析程序。没有特定于程序或特定于核心的 RAPL 域。您可以使用 rapl-read
选项运行 -m
以直接访问 MSR 以获取能量读数,然后是您的程序,然后再次运行 rapl-read
。两个读数之间的差异为您提供了每个支持域的能耗。请注意,您必须修改 rapl_msr()
函数,以便它在两次读数之间调用您的程序,而不仅仅是执行 sleep(1)
。否则,它只会在大约一秒钟内报告能源消耗,而与您的程序的能源消耗几乎没有任何相关性。
rapl-read
当前不支持 RKL(或任何最新的 Intel 处理器)。但是您可以通过首先从 cat /proc/cpuinfo
确定 CPU 模型,然后添加类似于当前支持的模型的宏定义(如 #define CPU_ROCKETLAKE model
)来轻松添加 RAPL 支持。我在 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。
使用 500.perlbench
输入的 test
基准测试似乎需要大约 3 分钟才能完成。很难知道 MSR_PKG_ENERGY_STATUS
是否回绕,因为报告的数字不是负数。
我认为最好在一个内核上运行 500.perlbench
,然后在另一个内核上运行每隔几秒读取一次 MSR_PKG_ENERGY_STATUS
的脚本。例如,您可以将 rdmsr -d 0x611
放入循环中,并在每次迭代中休眠若干秒。由于 500.perlbench
需要相对较长的时间才能完成,因此您不必完全同时启动这两个程序。通过这种方式,您可以模仿 perf stat -a -I 1000 -e power/energy-pkg/
的工作方式,如果英特尔平台上的内核支持事件 power/energy-pkg/
。
我已在 perf power consumption measure: How does it work? 讨论了英特尔基于 RAPL 的能源测量的可靠性。不过不知道有没有人验证过AMD的RAPL的准确性。我不清楚英特尔的 MSR_PKG_ENERGY_STATUS
和 AMD 的 Core::X86::Msr::PKG_ENERGY_STAT
之间的比较在多大程度上有意义。