最大并发节流

时间:2011-12-08 11:03:12

标签: c# .net multithreading .net-3.5

我希望这个问题有很多可能的解决方案,我可以自己提出一些解决方案,其中一些明显优于其他解决方案,但我确定没有一个是最优的,所以我有兴趣听取你真正的多线程大师在那里。

我有大约100件可以同时执行的工作,因为它们之间没有依赖关系。如果我按顺序执行这些操作,我的总执行时间大约是1:30。如果我在线程池中对每个工作进行排队大约需要2m,这告诉我,我试图一次做太多而且所有这些线程之间的上下文切换都否定了拥有这些线程的优势。

所以基于这个假设(如果这是错误的话,请随时把我击倒),如果我只排队到我系统中的核心数(这台机器上有8个),那么任何时候我都会工作减少上下文切换,从而提高整体效率(其他流程线程当然不能承受),任何人都可以建议这样做的最佳模式/技术吗?

BTW我使用的是smartthreadpool.codeplex.com,但我不必这样做。

2 个答案:

答案 0 :(得分:5)

一个好的线程池已经尝试为每个可用的核心提供一个活动线程。这不是每个核心有一个工作线程的问题,就好像一个线程阻塞(最常见的I / O)你想要另一个线程使用该核心。

尝试使用.NET threadpool可能值得一试,或者是Parallel类。

如果您的CPU是超线程的(4个物理上有8个虚拟核心),这可能是一个问题。平均而言,次穿线会使事情变得更快,但是有很多情况会使事情变得更糟。尝试为每个其他核心设置亲和力,看看它是否能带来改进 - 如果确实如此,那么这可能是超线程很糟糕的情况。

您是否必须再次收集结果,或在不同任务之间共享任何资源?这样做的成本可能远高于多线程的节省。也许它们是如此不必要的 - 例如如果您要锁定共享数据但只读取数据,则实际上并不需要使用大多数数据结构进行读取(如果没有写入,大多数但不是全部对于并发读取都是安全的。)

分工也可能是一个问题。假设单线程方法在内存区域中运行,但多线程方法为每个线程提供下一个内存来处理循环。这里每个核心都有更多缓存刷新,因为“好的下一位”实际上被另一个核心使用。在这种情况下,将工作分成更大的块可以解决它。

还有很多其他因素可以使多线程方法的性能比单线程更差,但是我可以立即想到这些因素。

编辑:如果你正在写一个共享商店,那么你可以尝试一个只丢掉任何结果的运行。这可能会缩小问题所在的范围。

答案 1 :(得分:1)

对我而言,你所说的似乎很奇怪。因为根据定义,线程池不应该使用超过系统可用资源(即如果你有4个核心,它将使用4个线程或接近这个数字的东西)。它使用一个队列,工作线程从该队列中获取任务并执行它们。因此,如果使用线程池,则无法真正拥有系统超额预订,除非您手动指定要使用的线程数,在您的情况下不建议这样做。

您是否尝试过使用标准C#ThreadPool课程?