I tried some crates like "sysinfo", but all of them returns the base speed of CPU. How to get the real current CPU Speed like the task manager in Rust?
Code below doesn't work.
use x86::time::rdtsc;
let a = rdtsc();
sleep(Duration::from_secs(1));
let b = rdtsc();
println!("{}", (b - a) / 1e6 as u64);
use sysinfo::{System, SystemExt, CpuExt};
let mut sys = System::new_all();
println!("{}", sys.cpus().first().unwrap().frequency());
Besides, I also tried to use WINAPI like CallNtPowerInformation, sadly it also returns a constant 3301, which is the base speed of my CPU(AMD Ryzen 5 5600H)
#[derive(Debug, Clone, Copy)]
struct CPUInfo {
Number: u32,
MaxMhz: u32,
CurrentMhz: u32,
MhzLimit: u32,
MaxIdleState: u32,
CurrentIdleState: u32,
}
impl CPUInfo {
fn new() -> Self {
Self {
Number: 0,
MaxMhz: 0,
CurrentMhz: 0,
MhzLimit: 0,
MaxIdleState: 0,
CurrentIdleState: 0,
}
}
}
let cpu_num: usize = 12;
let mut cpu_infos = vec![CPUInfo::new(); cpu_num];
unsafe {
use windows::Win32::System::Power::{ProcessorInformation, CallNtPowerInformation};
use windows::Win32::Foundation::{NTSTATUS, STATUS_SUCCESS, STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_DENIED};
let call_res = NTSTATUS(CallNtPowerInformation(
ProcessorInformation,
null(),
0,
transmute::<*mut CPUInfo, *mut c_void>(cpu_infos.as_mut_ptr()),
(size_of::<CPUInfo>() * cpu_num) as u32
));
if call_res == STATUS_SUCCESS {
//println!("{:?}", cpu_infos);
for i in 0..cpu_num {
println!("[CPU {:2} | {} Mhz] ", i, cpu_infos[i].CurrentMhz);
}
} else if call_res == STATUS_BUFFER_TOO_SMALL {
println!("Buffer too small.");
} else if call_res == STATUS_ACCESS_DENIED {
println!("Access denied.");
}else {
println!("Unknown error");
}
}
The ways else like reading the registry table, using the Win32_Processor WMI class also did no effect.
Can someone tell me what's wrong with my codes?