How do you limit CPU usage on Windows? (need code, not application)

There are programs that can limit processor use in Windows. For example, BES and ThreadMaster . I need to write my own program that does the same thing as these programs, but with different configuration options. Does anyone know how processor throttling (code) is performed? I'm not talking about setting the priority of the process, but about how to limit its use by the processor, for example, by 15%, even if there are no other processes competing for processor time.

Update: I need to be able to throttle all processes that are already running, and that I do not have access to the source code.

+4
source share
3 answers

Very simplified, it can work one way or another:

  • Create a periodic expected timer with some reasonable short wait time (maybe 100 ms). Get the "last" value for each corresponding process by calling GetProcessTimes once.
  • Forever cycle, timer lock.
  • Every time you wake up:
    • if GetProcessAffinityMask returns 0, call SetProcessAffinityMask(old_value) . This means that we paused this process at our last iteration, now we give it a chance to start again.
    • else call GetProcessTimes to get the "current" value
    • call GetSystemTimeAsFileTime
    • calculate delta by subtracting the last from the current
    • cpu_usage = (deltaKernelTime + deltaUserTime) / (deltaTime)
    • if it is more than you want the call old_value = GetProcessAffinityMask , followed by SetProcessAffinityMask(0) , which will disable this process.

This is basically a very primitive version of the scheduler that runs in the kernel, implemented in userland. It lays the process of "sleeping" for a short period of time if it has used more processor time than what you think is right. A more complex measurement may be required, perhaps after a second or 5 seconds (and probably desirable).

You may be tempted to suspend all threads in the process. However, it is important not to play with priorities and not to use SuspendThread unless you know exactly what the program is doing, as this can easily lead to deadlocks and other unpleasant side effects. Consider, for example, pausing a thread containing a critical section while another thread is still running and trying to get the same object. Or imagine that your process unloaded in the middle of a suspension of a dozen threads, leaving half of them running and the other half dead.

Setting the proximity mask to zero, on the other hand, simply means that from now on, no thread in the process receives more time fragments on any processor. Resetting affinity gives - atomically, at the same time - all threads can start again.

Unfortunately, SetProcessAffinityMask does not return the old mask as SetThreadAffinityMask , at least according to the documentation. Therefore, an additional call to Get... needed.

+4
source

You probably want to start the process in the job object and set the maximum CPU usage for the job object with SetInformationJobObject , with JOBOBJECT_CPU_RATE_CONTROL_INFORMATION .

+6
source

CPU usage is fairly easy to evaluate using QueryProcessCycleTime . Machine processor speed can be obtained from HKLM \ HARDWARE \ DESCRIPTION \ System \ CentralProcessor \\ ~ MHz (where is the processor number, one entry for each processor). Using these values, you can evaluate your processor utilization and use the processor if necessary using the Sleep () function to keep your usage within limits.

0
source

Source: https://habr.com/ru/post/1397319/


All Articles