性能-C ++中的CPU节流

我只是想知道是否有一种优雅的方法来为执行密集计算的特定线程设置最大CPU负载。

现在,我在线程中找到了最耗时的循环(它仅压缩),并使用GetTickCount()Sleep()以及硬编码值。 它可以确保循环持续一定时间,然后休眠一定的最短时间。 这项工作或多或少地完成了工作,即保证线程使用的CPU不超过50%。
但是,行为取决于CPU内核的数量(巨大的劣势),而仅仅是丑陋的(较小的劣势:))。
有任何想法吗?

Piotr Tyburski asked 2020-07-31T20:54:01Z
5个解决方案
20 votes

我不知道有任何API可以使操作系统的调度程序执行您想要的操作(即使您的线程是空闲优先级的,如果没有更高优先级的就绪线程,您的线程也会运行)。 但是,我认为您可以根据已经在做的事情即兴发挥一个相当优雅的调节功能。 本质上(我没有Windows开发机):

选择线程在每次迭代中休眠的默认时间。 然后,在每次迭代中(或在每第n次迭代中,使节流功能本身不会成为很大的CPU负载),

  1. 计算自上次调用限制功能以来,线程使用的CPU时间(我将其称为dCPU)。 您可以使用GetThreadTimes()API来获取线程已执行的时间。
  2. 计算自上次调用节流函数以来的实时时间量(我将其称为dClock)。
  3. dCPU / dClock是(一个CPU的)CPU使用百分比。 如果比您想要的高,请增加睡眠时间;如果比您想要的低,请减少睡眠时间。
  4. 让您的线程在计算的时间内进入睡眠状态。

根据看门狗计算CPU使用率的方式,您可能需要使用GetProcessAffinityMask()来找出系统有多少个CPU。 dCPU /(dClock * CPUs)是可用的总CPU时间的百分比。

您仍然必须为初始睡眠时间和增量/减量选择一些不可思议的数字,但是我认为可以对该算法进行调整,以使线程在相当接近确定的CPU百分比的情况下运行。

Matthew Xavier answered 2020-07-31T21:06:51Z
4 votes

在Linux上,您可以使用nice()更改线程的调度优先级。

Mark Harrison answered 2020-07-31T21:07:11Z
2 votes

我无法想到您想要的任何跨平台方式(或任何有保证的句号),但是当您使用GetTickCount时,您可能对跨平台不感兴趣:)

我会使用进程间通信并为密集的流程设置好级别,以获取您所需的内容,但是我不确定这是否适合您的情况。

编辑:我同意Bernard的观点,这就是为什么我认为进程而不是线程可能更合适,但它可能不适合您的目的。

sparkes answered 2020-07-31T21:07:40Z
2 votes

问题是在工作时想让CPU空闲是不正常的。 通常,您将后台任务设置为“ IDLE”优先级,然后让操作系统处理所有交互式任务未使用的CPU时间的调度。

在我看来,问题在于看门狗进程。

如果您的后台任务是CPU密集型的,那么您希望它占用其任务所有未使用的CPU时间。

也许您应该考虑修复看门狗程序?

Douglas Leeder answered 2020-07-31T21:08:14Z
0 votes

您可能可以更改线程的优先级,但是更改最大利用率可能需要轮询和黑客来限制发生的事情数量,或者使用可以设置进程最大利用率的OS工具。但是,在任何情况下我都不会这样做。

Aashishkebab answered 2020-07-31T21:08:34Z
translate from https://stackoverflow.com:/questions/1982/cpu-throttling-in-c