How to Disable Dynamic Frequency Scaling?
Asked Answered
T

3

5

I would like to do some microbenchmarks, and try to do them right. Unfortunately dynamic frequency scaling makes benchmarking highly unreliable.

Is there a way to programmatically (C++, Windows) find out if dynamic frequency scaling is enabled? If, can this be disabled in a program?

Ive tried to just use a warmup phase that uses 100% CPU for a second before the actual benchmark takes place, but this turned out to be not reliable either.

UPDATE: Even when I disable SpeedStep in the BIOS, cpu-z shows that the frequency changes between 1995 and 2826 GHz

Tetrahedron answered 20/10, 2010 at 7:20 Comment(0)
T
9

In general, you need to do the following steps:

  • Call CallNtPowerInformation() and pass SystemPowerCapabilities to InformationLevel parameter, set lpInputBuffer and nInputBufferSize to NULL, then set lpOutputBuffer to SYSTEM_POWER_CAPABILITIES structure, and set nOutputBufferSize to the size of the structure. After this first call, SYSTEM_POWER_CAPABILITIES structure containing the current system power capabilities. To check whether the system supports processor throttling, read the value of ProcessorThrottle.

  • There are other two members we are interested in, they are, ProcessorMinThrottle and ProcessorMaxThrottle; they represents the minimum and maximum level of system processor throttling supported, expressed as a percentage. If both members has already values 100%, this means CPU throttling is currently disabled, so you don't need to reconfigure it.

  • To disable CPU throttling, you need to set ProcessorMinThrottle and ProcessorMaxThrottle to 100%. To do this, call CallNtPowerInformation() again and pass SystemPowerCapabilities to InformationLevel parameter; but now, set lpInputBuffer to the SYSTEM_POWER_CAPABILITIES structure in which the two members has been set to 100%. I'm sure you know what to do next.

In non-programmatic way, you can also get/set Windows Power Options using the Windows built-in command-line tools, that is, PowerCfg.

Further Reading

Telephoto answered 20/10, 2010 at 9:16 Comment(3)
Thanks for this. This was useful. One question, though. Is this permanent or just for the time the application runs?Simmer
From the MSDN: SystemPowerCapabilities 4 - The lpInBuffer parameter must be NULL, otherwise, the function returns ERROR_INVALID_PARAMETER. Did someone actually verify this works?Rockandroll
ProcessorThrottle is constantly FALSE for me and the throttle percentages are constantly 0, although I'm certain that my Laptop does frequency scaling. CallNtPowerInformation returned ERROR_SUCCESS. I'm not sure what is going on.Pinguid
P
2

So far, none of the above CallNtPowerInformation options worked for me. The relevant ProcessorThrottle field of SYSTEM_POWER_CAPABILITIES was FALSE and changing some SYSTEM_POWER_POLICYs didn't work.

However, https://www.geeks3d.com/20170213/how-to-disable-intel-turbo-boost-technology-on-a-notebook/#_24 outlines a way to make an option available in the power management settings.

With ProcMon, I was able to trace it back to the following registry manipulations:

  1. Read the ActivePowerScheme SZ value under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\User\PowerSchemes to get the active power plan
  2. Set the ACSettingIndex and/or DCSettingIndex DWORD under Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\User\PowerSchemes\<above active power plan GUID>\54533251-82be-4824-96c1-47b60b740d00\be337238-0d82-4146-a960-4f3749d470c7 to 0 (Disabled, or whatever you choose) from 2 (High)

Unfortunately, the relevant keys are owned by the system, which either means you have to prompt the user (which has to have admin access) to change the permissions of the key or you have to use powercfg to manipulate the setting. The latter is preferrable and actually seems to work, even without admin access (courtesy of https://learn.microsoft.com/en-us/windows-server/administration/performance-tuning/hardware/power/power-performance-tuning#processor-performance-boost-mode):

powercfg -setacvalueindex scheme_current sub_processor PERFBOOSTMODE 0
powercfg -setdcvalueindex scheme_current sub_processor PERFBOOSTMODE 0
powercfg -setactive scheme_current
Pinguid answered 25/8, 2018 at 10:13 Comment(2)
Are you on a Skylake or later CPU? Skylake introduced the ability for the OS to fully hand off control of P-states (frequency scaling) to the hardware. In older CPUs, that was only done for Turbo frequencies (above the "rated" frequency, where HW needs to be able to back off on its own). But in Skylake, Turbo isn't as "special", and I think the way the OS would disable it is different in hardware-P-state mode. Anyway, this might explain why other answers no longer work. (I don't use Windows, so IDK the details.)Cristobalcristobalite
Thanks! That might indeed explain why it "doesn't work" anymore.Pinguid
T
0

In Windows XP and later CPU speed is managed by power policy. Doesn't it turn off the scaling if you set "Max performance" mode in Windows power management dialog?

There're also some third party tools - SpeedSwitchXP for example.

Programmatically this could be done, I suppose, using CallNtPowerInformation function.

Teeny answered 20/10, 2010 at 7:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.