C++:有意限制CPU使用率

7

在我们公司,我们经常在CPU压力下测试我们的USB和FireWire设备的性能。

有一个测试代码,我们运行它来加载CPU,通常用于非正式测试以查看我们的设备性能会发生什么变化。

我查看了这个代码,它是一个简单的循环,它递增一个计数器并根据新值进行计算,将结果存储在另一个变量中。

运行单个实例将使用CPU的1 / X,其中X是核心数。

因此,例如,如果我们在一台8核PC上想要查看我们的设备在50% CPU使用率下的运行情况,我们可以同时打开四个实例,依此类推...

我在想:

  1. 是什么决定了使用多少CPU?它是否只在单线程应用程序的单个线程上尽可能快地运行所有内容?

  2. 是否有一种方法可以自愿限制程序可以使用的最大CPU使用率?我可以想到一些“懒惰”的方法(添加睡眠命令或其他东西),但是否有一种方法可以将其限制为可用CPU的某个指定百分比?


  1. CPU 尽可能快地运行代码。
  2. 没有“随意”的方式,你无法强制限制。
- David Heffernan
@Ben 噢,那很新鲜,不是吗? - David Heffernan
2
@David:或许对于Windows来说是新的,但实时操作系统早已提供了CPU分区。 - Ben Voigt
4个回答

8

关于 Windows 7Linux 的 CPU 配额。

同样也适用于 QNX(即黑莓平板操作系统)LynuxWorks

如果链接失效,文章名称如下:

  • Windows -- "Windows Server 2008 R2 和 Windows 7 中的 CPU 速率限制"
  • Linux -- "Linux 的 CPU 使用率限制器"
  • QNX -- "自适应分区"
  • LynuxWorks - "分区操作系统" 和 "ARINC 653"

1
1. 操作系统通常决定如何调度进程以及它们应该在哪个CPU上运行。它基本上为那些准备运行的进程(未标记为终止并且未被阻塞等待某些I/O、事件等)保持就绪队列。每当一个进程用完其时间片或者阻塞时,它基本上会释放一个处理核心,操作系统会选择另一个进程来运行。现在,如果你有一个进程总是准备好运行并且永远不会阻塞,那么这个进程本质上会在可以运行时运行,从而将处理单元的利用率推向100%。当然,这只是一个简化的描述(例如有进程优先级之类的东西)。
2. 通常没有通用的方法来实现这一点。您使用的操作系统可能提供某种机制来实现这一点(一些CPU配额之类的东西)。您可以尝试测量经过了多长时间与您的进程使用了多少CPU时间,然后让您的进程睡眠一段时间,以实现所需的CPU利用率近似值。

  1. 在Firewire或USB驱动程序中,优先级起着关键作用,因为它们将抢占任何用户进程。
  2. 当然有一种通用的方法,你可以实现一个反馈循环尝试保持处理器时间是墙钟时间的某个倍数。
- Potatoswatter

0

你已经基本回答了自己的问题!

消耗大量CPU的代码的关键特征是它永远不会做任何阻塞的事情(例如等待网络或文件I/O),也永远不会自愿放弃时间片(例如sleep()等)。

另一个诀窍是代码必须执行一些编译器无法优化掉的操作。因此,最有可能的是,你的CPU消耗代码会根据最后的循环计算输出某些内容,或者仅仅是没有进行优化的编译,以便优化器不会试图删除无用的循环。既然你想要加载CPU,那么优化也没有意义。

正如你所猜测的那样,符合这个描述的单线程代码将占用CPU核心,除非操作系统拥有比它们运行的核心更多的这些进程--然后它将轮流调度它们,每个进程的利用率都是100%的一部分。


0
问题不在于CPU空闲的时间有多少,而是你的代码启动执行需要多长时间。谁在乎它是空闲还是在做低优先级的忙碌工作,只要延迟很低就行了。
你的问题根本上是使用了合成基准测试,可能是为了获得可复现的结果。但是合成基准测试往往产生无意义的结果,所以可复现性是没有意义的。
查看你的错误数据库,找到实际客户投诉,并使用真实的软件和测试硬件重现一个确实导致某人不满的情况。与硬性、有意义的性能需求平行开发性能测试。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接