3

我有一个项目可以动态加载实现指定接口的未知程序集。除了实现我的接口之外,我不知道程序集的内容或目的。

我需要以某种方式限制这些组件可用的处理能力。处理器优先级不是我想要的。我不能使用秒表并为程序集分配一定的时间来运行,因为服务器可能会很忙。

理想情况下,我想指定一些完全独立于负载的 CPU 使用量度量。如有必要,我可以在自己的进程中运行程序集。

有没有办法以某种方式测量给定线程(或进程,尽管线程是最佳的)的总超时 CPU 使用率?

我可以使用进程性能计数器,还是我怀疑它们太不可靠了?虽然我不需要循环精度,但我需要相当高的精度来限制分配给每个程序集执行的计算能力。


根据我的情况推断一下。我不寻找进程优先级的原因是我不害怕耗尽我的资源,我只需要确保我可以测量给定程序集使用的“多少”资源 - 因此我关于服务器的观点是任意的忙碌的。

想象一下您有两个程序集 X 和 Y 的示例场景。它们中的每一个都实现了一个给定的算法,我想对哪个程序集可以最快地完成工作进行原始测试。我运行每个程序集并让它运行,直到它使用“Z”资源,此时我评估哪个程序集做得最好。在这种情况下,我不介意一个程序集以 100% CPU 运行 3 秒,而另一个程序集以 2% CPU 运行 5 分钟 - 总资源使用量很重要。

我想我也许可以使用 CPU time perfcounter 来做一个粗略的限制。在一个新线程中运行每个程序集并让它运行,直到它使用给定的 CPU 时间,此时我将终止该进程并评估结果。我只是怕它不够准确。

4

3 回答 3

1

我很好奇为什么你认为你不能(不应该)为此使用优先级。微软的人们花了很长时间开发任务计划程序,它让所有线程/进程在 CPU 上都获得了平等的机会。如果您的机器上运行了更高优先级的进程,并且您不希望您的程序/第 3 方 dll 影响该其他程序,那么只需将您的优先级设置为低于该其他程序,您不会。这就是优先级的目的。即使您的程序以 100% 的速度最大化 CPU,其他程序也会在它想要运行时取代您的进程或线程,即使优先级相同,但尤其是当它具有更高的优先级时。

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

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


如果您在多 CPU 机器上运行,另一种选择是使用亲和力将您的程序限制在某些内核上。例如,在四核机器上,如果您将程序限制为 core3,那么它可能会过度使用并最大限度地使用该 cpu,而系统的其余部分仍将具有 3 个内核以保持高可用性。

于 2008-10-25T20:31:39.200 回答
1

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

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

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

于 2008-10-27T16:55:46.250 回答
1

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

不幸的是,我认为您没有一种简单的方法可以通过配置加载 DLL 的 AppDomain 来做到这一点。您可能必须重新实现 Terrarium 的功能。

于 2008-10-25T18:25:39.080 回答