我试图检测我的CPU当前的p-state状态。我发现对于我的Ryzen 1700x系统,即使核心明显不处于该状态,p-state状态MSR(C001_0063)始终返回2。我认为它可能在初始BIOS(v0403)中起作用,但现在无法下载1。
我的CPU已经超频2到3.8GHz。我使用cpufreq-set
来固定速度,并使用cpufreq-info
进行验证:
analyzing CPU 0:
driver: acpi-cpufreq
CPUs which run at the same hardware frequency: 0
CPUs which need to have their frequency coordinated by software: 0
maximum transition latency: 4294.55 ms.
hardware limits: 2.20 GHz - 3.80 GHz
available frequency steps: 3.80 GHz, 2.20 GHz
available cpufreq governors: ondemand, conservative, performance, schedutil
current policy: frequency should be within 3.80 GHz and 3.80 GHz.
The governor "performance" may decide which speed to use
within this range.
current CPU frequency is 3.80 GHz (asserted by call to hardware).
以下是一个小测试程序,显示核心#0的寄存器值以及相对于P0状态的有效速度。需要root权限。在我的电脑上,它在负载下不断地打印pstate: 2, speed: 99%
。
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char** argv)
{
uint64_t aperf_old = 0;
uint64_t mperf_old = 0;
int fd;
fd = open("/dev/cpu/0/msr", O_RDONLY);
uint64_t pstate_limits;
pread(fd, &pstate_limits, sizeof(pstate_limits), 0xC0010061);
printf("pstate ranges: %d to %d\n", (int)(pstate_limits & 0x07), (int)((pstate_limits >> 4) & 0x07));
for(;;)
{
uint64_t pstate;
uint64_t pstate_req;
uint64_t aperf;
uint64_t mperf;
pread(fd, &pstate_req, sizeof(pstate_req), 0xC0010062);
pread(fd, &pstate, sizeof(pstate), 0xC0010063);
pread(fd, &aperf, sizeof(aperf), 0x000000E8);
pread(fd, &mperf, sizeof(mperf), 0x000000E7);
printf("pstate: %d, requested: %d", (int)(pstate & 0x07), (int)(pstate_req & 0x07));
if (mperf_old != 0 && mperf_old != mperf)
{
printf(", speed: %d%%", (int)(100 * (aperf - aperf_old) / (mperf - mperf_old)));
}
putchar('\n');
mperf_old = mperf;
aperf_old = aperf;
sleep(1);
}
}
我以前在FX-8350上使用了类似的方法,但现在为什么行不通了?欢迎测试结果。
系统信息:
- CPU:Ryzen 1700X,P0和P1为3.8GHz3,P2为2.2GHz
- 主板:华硕Prime X370-A,BIOS版本3401
- 操作系统:Debian 7.1,内核4.9.0
更新:我已经更改了代码以打印请求的pstate,并且该寄存器正在按预期更改。各种基准测试也证实了实际的CPU速度正在变化。
1由于某种晦涩的原因,BIOS备份功能被禁用,因此我无法在更新之前制作副本。
2我会在有机会时运行默认设置的测试。
3不知道为什么会重复。