交叉AppDomain线程池W / O上下文切换

时间:2012-01-05 02:37:26

标签: c# .net clr threadpool appdomain

我们的应用程序在很大程度上受CPU限制,可以尽快处理数十亿个元组的数据。它使用多核,并很快转移到云中分布。

所以我们的目标是尽可能高效地使用CPU。这个问题是关于如何保持高水平的性能将允许插件在运行时动态加载/卸载。

请理解,虽然通过AppDomains进行通信很容易,但“简单”方法都不能满足上述性能要求。因此,这些问题讨论了常见技术太慢的原因和进一步的要求以及我们要解决的具体问题。

为了实现性能,应用程序设计为通过“消息传递”在组件之间进行通信,这意味着我们有一个用户模式任务调度程序,以保持这些线程忙碌而不必(除非必要时)放弃任何时间片或上下文切换到操作系统。

在.NET中卸载DLL的唯一方法是通过AppDomains。但是,为了保持上述高性能,这意味着线程池(我们拥有自己的本土线程池)必须能够在各种不同的AppDomain中执行任务。

更具体地说,为数十个AppDomain中的每一个分别创建单独的线程然后竞争CPU将是一种糟糕的性能。由于操作系统在线程之间花费了大量的时间上下文切换,因此与CPU绑定工作的内核相比,线程数将超过内核。

在我们自己的线程池与任何类型的体面性能交叉进入其他AppDomain之后,似乎经过初步研究零效率方式。即使对方法没有参数,远程处理或序列化都是非常慢的。

请注意,这与数据共享无关。我们不希望将线程调用用于不同的AppDomain来传递数据。相反,我们希望通过套接字和内存映射文件在AppDomains之间共享数据,以获得最佳飞行性能,就像正确的进程间通信一样。所以这个问题只涉及让线程在AppDomains上运行。

Stackoverflow上的以下链接超过2年,暗示了利用.Net的CLR中的内置线程池,它指出它跨越其他AppDomain来执行任务。 MS文档还验证CLR线程池是否跨所有AppDomain运行。

.Net How to create a custom ThreadPool shared across all the AppDomain of a process?

在阅读文档之后,如何在AppDomain中使用内置线程池,而在跨越AppDomain时不允许任何上下文切换?

所以设计目标是如何轮换线程(每个核心一个)来频繁检查每个AppDomain中任务的“运行队列”,看看是否有工作要做,然后转移到下一个AppDomain?依此类推,循环遍历每个AppDomains调度程序?如何做到这一点没有等待任何上下文切换开销或远程处理或编组?

当然,请注意,我们会巧妙地将AppDomains分配给每个线程,以避免L1缓存未命中,从而避免出现硬件瓶颈。

我们想知道的另一个想法是编写我们自己的自定义CLR主机。似乎C ++ API允许实现我们自己的线程池。有谁知道这是否会允许上述功能?如果是这样,这是通过非托管代码实现它的唯一方法吗?

0 个答案:

没有答案