Windows 无法在Powershell或Python中获取当前CPU频率

Windows 无法在Powershell或Python中获取当前CPU频率,windows,powershell,cpu,frequency,Windows,Powershell,Cpu,Frequency,我试图以某种方式编程记录我的Windows10机器的CPU频率。但是,我显然无法获得任务管理器中显示的当前频率 在Powershell中,使用 get-wmiobject Win32_Processor -Property CurrentClockSpeed 只返回一个正是最大时钟速度的时钟速度(尽管我可以在任务管理器中看到它没有运行那么高) 我甚至尝试过这个解决方案:但它只给了我一个静态值=最大值 甚至python的psutil也只返回静态值 有没有人知道如何绕过这个问题,并以某种方式记录每

我试图以某种方式编程记录我的Windows10机器的CPU频率。但是,我显然无法获得任务管理器中显示的当前频率

在Powershell中,使用

get-wmiobject Win32_Processor -Property CurrentClockSpeed
只返回一个正是最大时钟速度的时钟速度(尽管我可以在任务管理器中看到它没有运行那么高)

我甚至尝试过这个解决方案:但它只给了我一个静态值=最大值

甚至python的psutil也只返回静态值

有没有人知道如何绕过这个问题,并以某种方式记录每x秒的CPU频率


任何帮助都将不胜感激,谢谢

TLDR:要查找当前处理器频率,必须使用
%处理器性能计数器:

$MaxClockSpeed = (Get-CimInstance CIM_Processor).MaxClockSpeed
$ProcessorPerformance = (Get-Counter -Counter "\Processor Information(_Total)\% Processor Performance").CounterSamples.CookedValue
$CurrentClockSpeed = $MaxClockSpeed*($ProcessorPerformance/100)

Write-Host "Current Processor Speed: " -ForegroundColor Yellow -NoNewLine
Write-Host $CurrentClockSpeed

关于为什么查询WMI
Win32_处理器
CurrentClockSpeed
似乎总是返回最大频率,而不是实际的“当前时钟速度”的更深入解释?事实上,为什么几十个WMI/CMI/Perfmon计数器似乎都返回“错误”频率?如果CPU-Z和任务管理器可以得到它,我们需要做什么才能得到“实际”频率?要回答这个问题,我们需要了解
CurrentClockSpeed
实际返回的是什么

CurrentClockSpeed
的WMI文档中:

处理器的当前速度,以MHz为单位。此值来自 中处理器信息结构的当前速度成员 SMBIOS信息

太好了!有人会认为,这个简单的查询应该可以得到当前的频率。这在十几年前很管用,但现在不行了;因为它实际上只适用于两种非常特殊的情况:

  • 当您的处理器仅以其定义的存储速度运行时
  • 当Windows要求移动处理器以不同速度运行时(例如,移动到电池模式)
  • 在启动时,Widows获取处理器信息和当前时钟速度。大多数人都在以推荐的设置运行处理器,因此
    当前时钟速度==最大时钟速度
    ,这意味着这两个数字始终匹配。更改电源状态时,Windows将更改频率,
    CurrentClockSpeed
    也将更改

    现在,十几年前发生了什么事情使得
    CurrentClockSpeed
    完全不准确/不相关?你最终可以感谢英特尔。多亏了一项新技术,他们基本上把这个理想值从水中吹走了

    涡轮增压与此有什么关系

    Turbo Boost根据处理器上的电流负载在电压、电流和热包络范围内动态更改处理器频率。几乎所有的现代处理器现在都有省电模式,可以根据当前的市场流行语(如Turbo Boost(上升)、Cool'N'Quiet(下降))动态改变频率

    关键点是:所有这些频率的上/下/关闭/打开都是自动完成的,而Windows不知道它。因为Windows不知道,所以在大多数情况下,
    CurrentClockSpeed
    值可能完全不准确。事实上,Microsoft知道这一点,当您打开性能监视器,查看
    处理器性能/处理器频率
    下的描述时:

    Processor Frequency是中当前处理器的频率 兆赫。一些处理器能够调节其频率 在Windows的控制之外处理器频率将不会 准确反映这些系统上的实际处理器频率。使用 处理器信息\%改为处理器性能

    幸运的是,此描述为我们提供了获取实际值所需的提示:
    处理器信息\%Processor Performance

    我们可以使用访问当前处理器性能,如下所示:

    PS C:\> Get-Counter -Counter "\Processor Information(_Total)\% Processor Performance"
    
    Timestamp                 CounterSamples
    ---------                 --------------
    2020-01-01 1:23:45 AM     \\HAL9256\processor information(_total)\% processor performance :
                              153.697654229441
    
    在这里,您可以看到,我的处理器的性能是处理器频率的153%(也就是说,是的,涡轮增压!)。然后,我们从
    CIM_处理器
    类查询
    MaxClockSpeed
    (您也可以使用
    WMI_处理器
    ):

    为了计算出实际时钟速度:

    $MaxClockSpeed = (Get-CimInstance CIM_Processor).MaxClockSpeed
    $ProcessorPerformance = (Get-Counter -Counter "\Processor Information(_Total)\% Processor Performance").CounterSamples.CookedValue
    $CurrentClockSpeed = $MaxClockSpeed*($ProcessorPerformance/100)
    
    Write-Host "Current Processor Speed: " -ForegroundColor Yellow -NoNewLine
    Write-Host $CurrentClockSpeed
    
    然后,如果需要每2秒运行一次,将其包装成一个循环(
    Ctrl+C
    停止):


    虽然该代码用于接收高于基准时钟的值,但它似乎与我的Zen 3 Ryzen 5900X上的HWInfo64不匹配。直接比较起来,它总是低几个兆赫。此外,对我来说(_Total)条目报告更低,我需要直接查询各种核心以获得更精确的测量。例如:
    处理器信息(_Total):4725,68
    vs
    处理器信息(0,2):4837,54
    @sp00n您指出了一个有趣的案例,它是由Zen 3 Ryzen直接创建的。上面的计算假设,虽然时钟速度可以动态变化,但变化同时发生在所有内核上。使用Zen 3 Ryzen,每个核心可以在不同的时钟速度下运行和/或空闲时休眠。这将使这些基本计算偏离相当大的一部分(特别是当一个内核处于休眠状态时)。在您的情况下,是的,您必须查询每个单独的内核和电源状态,以“正确”计算时钟速度。为各个内核报告的值仍然低于HWInfo64或Ryzen Master报告的值,我不知道为什么。最后,我甚至自己用原始性能计数器值而不是已经“煮熟”的值进行了计算(需要两个快照来计算值),但这只给了我更精确的数字。它仍然缺少一对夫妇的专用工具的价值,一个兆赫
    $MaxClockSpeed = (Get-CimInstance CIM_Processor).MaxClockSpeed
    $ProcessorPerformance = (Get-Counter -Counter "\Processor Information(_Total)\% Processor Performance").CounterSamples.CookedValue
    $CurrentClockSpeed = $MaxClockSpeed*($ProcessorPerformance/100)
    
    Write-Host "Current Processor Speed: " -ForegroundColor Yellow -NoNewLine
    Write-Host $CurrentClockSpeed
    
    $MaxClockSpeed = (Get-CimInstance CIM_Processor).MaxClockSpeed
    
    While($true){
        $ProcessorPerformance = (Get-Counter -Counter "\Processor Information(_Total)\% Processor Performance").CounterSamples.CookedValue
        $CurrentClockSpeed = $MaxClockSpeed*($ProcessorPerformance/100)
    
        Write-Host "Current Processor Speed: " -ForegroundColor Yellow -NoNewLine
        Write-Host $CurrentClockSpeed
    
        Sleep -Seconds 2
    }