限制汇编执行的CPU周期数

发布于 2024-07-08 01:39:09 字数 745 浏览 10 评论 0原文

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

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

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

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

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


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

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

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

I have a project that dynamically loads in unknown assemblies implementing a specified interface. I don't know the contents or purposes of the assembly, other than it implementing my interface.

I need to somehow restrict the amount of processing power available to these assemblies. Processor priority is not what I'm looking for. I can't use a stopwatch and assign a certain amount of time for the assembly to run as the server might be arbitrarily busy.

Optimally I'd like to specify some completely load independent measure of CPU usage. I can run the assemblies in their own process if necessary.

Is there any way to somehow measure the total over-time CPU usage of a given thread (or process, though thread would be the optimal)?

Might I use the process performance counters, or are they, as I suspect, too unreliable? While I don't need to-the-cycle accuracy, I would need rather high accuracy to limit the computing power allocated to each assembly execution.


To extrapolate a bit on my situation. The reason I'm not looking for prioritization of the processes is that I'm not afraid of exhausting my resources, I just need to ensure I can measure "how many" resources a given assembly uses - thus my point about the server being arbitrarily busy.

Imagine the example scenario where you have two assemblies X and Y. Each of them implement a given algorithm and I want to do a primitive test of which assembly gets the job done quickest. I run each assembly and let it run until it's used "Z" resources, at which point I evaluate which assembly did the best job. In this case, I don't mind if one assembly runs at 100% CPU for three seconds, while the other one runs for 2% CPU over 5 minutes - it's the total resource usage that's important.

I'm thinking I might be able to use the CPU time perfcounter to do a crude limitation. Runt each assembly in a new thread and let it run until it's used a given amount of CPU time, at which point I'll kill the process and evaluate the results. I'm just afraid it won't be accurate enough.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

神魇的王 2024-07-15 01:39:09

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

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

I think I remember that Terrarium did something similar to what you want I suggest taking a look at http://www.codeplex.com/terrarium2.

Unfortunately I don't think you have a easy way to do this by just configuring the AppDomain where you load the DLLs. You'll probably have to reimplement what Terrarium does.

她说她爱他 2024-07-15 01:39:09

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

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

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


如果您在多 CPU 计算机上运行,​​另一个选择是使用亲和力将程序限制为某些内核。 例如,在四核机器上,如果您将程序限制为 core3,那么它可能会变得疯狂并最大化该 cpu,而系统的其余部分仍将有 3 个核心来维持高可用性。

I'm curious why you think you can't (shouldn't) use priority for this. The people at Microsoft have spent a very long time developing the Task Scheduler that gives all threads/processes an equal shot at the CPU. If you have higher priority processes running on your machine and you don't want your program/3rd party dlls to impact that other program, then simply set your priority lower than that other program, and you won't. That's what priority is for. Even if your program is maxxing out the CPU at 100%, that other program will displace your process or threads when it wants to run, even when priorites are equal, but especially when it has a higher priority.

If you're still determined, then you're going to have to either use PerformanceCounter or a Win32 API to monitor your process/thread and use Thread.Sleep's when you exceed your threshold. This seems overly messy.

A better option (IMO) is to use a custom threadpool that lets you configure the max number of threads, queue up a thread for each assembly you load, set their priority one below normal, and monitor to determine the max number of threads that yields your desired performance limitation. A very good custom threadpool can be found here. (The .NET threadpool won't allow you to limit things which is why you need to use a custom threadpool.)


Another option if you're running on a multi-cpu machine is to use affinity to limit your program to certain cores. On a four-core machine, if you limit your program to core3, for instance, then it can go hog-wild and max out that cpu and the rest of the system will still have 3 cores to maintain high availability.

樱桃奶球 2024-07-15 01:39:09

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

因此,从技术上来说,将单核系统上的线程执行限制为比该计时器更细粒度的东西应该是不可能的。

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

The way most X86 operating systems work is to use preemptive thread scheduling. The OS initializes a timer on the mother board that will send an interrupt to the processor every, say 100ms. (This is an execution slice. Well behaving computationally intensive programs should typically start to wait for something putting them in wait queue before this limit.) When the processor gets the interrupt, it switches execution to the OS kernel.

Thus it should be technically impossible to limit thread execution on a single core system to something more granular than this timer.

With "fair" scheduling, you could have a spinning manager (since you're not interested in saving power) that looks at execution time of the respective threads and terminates them if they've executed for too long.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文