限制程序集执行的CPU周期数量

3
我有一个项目,它会动态加载一些实现特定接口的未知程序集。我不知道这些程序集的内容或目的,除了它们实现了我的接口之外。
我需要以某种方式限制这些程序集可用的处理器运算能力。我不是在寻找处理器优先级。我不能使用秒表并分配一定时间让程序集运行,因为服务器可能会任意繁忙。
最理想的情况是我可以指定一些完全独立于负载的CPU使用度量。如果必要,我可以在它们自己的进程中运行这些程序集。
是否有办法以某种方式测量给定线程(或进程,尽管线程是最佳选择)的总CPU使用率?
我可以使用进程性能计数器吗?还是它们像我怀疑的那样不太可靠?虽然我不需要精确到周期的准确性,但我需要相当高的准确性来限制分配给每个程序集执行的计算能力。
稍微解释一下我的情况。我没有寻找进程优先级的原因是我不担心耗尽资源,我只需要确保我可以衡量每个程序集使用了多少资源 - 因此我提到服务器可能任意繁忙。
想象一下这样的场景:你有两个程序集X和Y。它们中的每一个实现了一个给定算法,我想做一个简单的测试,看看哪个程序集能够最快地完成任务。我运行每个程序集并让它一直运行,直到使用了“Z”个资源,然后评估哪个程序集执行得最好。在这种情况下,如果一个程序集在三秒钟内以100%的CPU运行,而另一个程序集在5分钟内以2%的CPU运行,我并不介意 - 重要的是总资源使用量。
我正在考虑使用CPU时间性能计数器来进行粗略限制。在新线程中运行每个程序集,并让它运行,直到它使用了一定量的CPU时间,然后我将杀死该进程并评估结果。我只是担心它不够准确。

你加载的程序集是否会生成子进程? - jmcd
不,子程序集不会生成任何子进程。通常情况下,子进程只会运行非常基本的代码(使用CAS严格限制)。 - Mark S. Rasmussen
请参考 http://stackoverflow.com/questions/448811/calculate-total-cpu-usage/449081#449081。在 Windows 操作系统中,可以使用 GetProcessTimesQueryProcessCycleTime(仅适用于 Vista 或更高版本)来计算 CPU 的总使用率。 - rwong
3个回答

1

我记得Terrarium做了类似于你想要的东西,建议看一下http://www.codeplex.com/terrarium2

不幸的是,我认为你不能通过仅配置加载DLL的AppDomain来轻松实现这一点。你可能需要重新实现Terrarium所做的事情。


1

我很好奇你为什么认为你不能(不应该)使用优先级来解决这个问题。微软的任务计划程序花费了很长时间开发,使所有线程/进程都有平等的机会获得CPU。如果您的机器上运行着更高优先级的进程,并且您不希望您的程序/第三方dll影响其他程序,则只需将您的优先级设置为低于其他程序,您的程序就不会影响到其他程序。这就是优先级的作用。即使您的程序将CPU占用率最大化为100%,当其他程序想要运行时,它也会取代您的进程或线程,即使优先级相等,但特别是当它具有更高的优先级时。

如果您仍然坚持要这样做,那么您将不得不使用PerformanceCounter或Win32 API来监视您的进程/线程,并在超过阈值时使用Thread.Sleep。这似乎过于混乱。

我认为更好的选择是使用自定义线程池。您可以配置最大线程数,为每个加载的程序集排队一个线程,并将它们的优先级设置为低于正常值。通过监控以确定产生所需性能限制的最大线程数。这里可以找到一个非常好的自定义线程池here。(.NET线程池不允许您限制事物,这就是为什么需要使用自定义线程池的原因。)

如果您正在运行多CPU机器,则另一个选择是使用亲和力来限制程序在某些核心上运行。例如,在四核机器上,如果您将程序限制在core3上,则它可以疯狂地占用该CPU,并且其余系统仍然有3个核心来维护高可用性。


1
我不想限制峰值处理器使用率,而是有兴趣限制总体CPU使用率。想象一种情况,你有两个程序集X和Y。你让它们各自运行,直到它们使用了完全相同的CPU资源,然后你评估哪一个做得更好。 - Mark S. Rasmussen
我明白了... 我建议你阅读一些关于System.Diagnostics命名空间的文档。PerformanceCounter和ProcessThread都有你可以使用的东西。第三方分析器(在Google上搜索“.Net Profiler”)也可能是你可以使用的工具。Intel也有一个叫做VTune的工具。 - sliderhouserules

1

大多数X86操作系统的工作方式是使用抢占式线程调度。操作系统在主板上初始化一个计时器,每隔100毫秒向处理器发送一个中断信号。(这是一个执行片段。良好行为的计算密集型程序通常应该在此限制之前开始等待某些东西并将它们放入等待队列中。)当处理器接收到中断信号时,它会将执行切换到操作系统内核。

因此,在单核系统上限制线程执行到比这个计时器更细粒度的东西在技术上应该是不可能的。

通过“公平”调度,您可以拥有一个旋转管理器(因为您不关心节能),它查看各个线程的执行时间,并在它们执行时间过长时终止它们。


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