ThreadPool回调紧密循环 - 100%CPU

Nat*_*ace 5 c# cpu threadpool

我的算法中有一个方法,它在非常大的数据集上运行非常紧密的循环.我最初写它是单线程,这很好,但它花了很长时间.我现在想要加速它,所以我现在使用ThreadPool来并行化工作.问题是这导致我的CPU使用率达到95-100%,这是我所期望的.但是,我的表现有了很大的提升,但我认为如果我可以减少所有的上下文切换,我可以做得更好.这也导致我的其他程序有点滞后,因为它们必须与线程争夺CPU资源.

我的问题是我应该怎么做呢?我唯一能想到的是限制一次运行的线程数,但这可能会使我的算法变慢,因为一次只能运行几个线程.我不想在我的线程中添加睡眠,因为我只需要算法尽快运行完成.

编辑:有几个人提到使用TPL.我认为这是一个好主意,但不幸的是我忘了提到我使用.NET 3.5,因为父应用程序尚未发布使用.NET 4的版本.

Kei*_*thS 6

这完全是关于资源管理.您的程序目前占用了所有资源,因此其他程序可以减少对它们的访问.您需要平衡"我只需要算法尽快运行到完成"部分与"这也会导致我的其他程序有点滞后,因为他们必须对抗CPU资源的线程".它们是相互排斥的; 您无法在特定计算机上以尽可能快的速度运行应用程序,也可以使其他应用程序完全响应.在任何时间段内CPU都可以做多少就是一个限制.

就效率提升而言,您可以做一些事情:

  • 不要将ThreadPool用于超优化的线程算法.ThreadPool非常适合简单的"关闭并执行此操作并让我知道您已完成"操作.但是,如果您正在寻求优化,则可以避免使用ThreadPool添加额外级别的线程调度(在CPU和OS固有的开销之上)所固有的开销.您还可以对ThreadPool中的线程进行更有限的控制,这意味着无法为单个线程分配处理器关联(负载平衡)和优先级(给予线程更多或更少时间)等优化.尝试创建简单的线程,或者查看具有许多策略的TPL,以完成多项工作(并非所有这些都需要首先进行线程化).

  • 是的,你希望能够"节流"线程数.这可以通过减少程序对它的需求来允许其他程序占用一些CPU时间,但正如我所说,多线程中也存在固有的开销.经验法则是,如果CPU的主动运行线程数超过两倍,因为它具有"执行单元"(这些是CPU芯片上的物理内核,而"逻辑处理器",如分裂一个内核的超线程技术)到两个),然后操作系统将花费更多的时间来调度线程并在它们之间切换("缓存 - 颠簸"),而不是花在实际运行线程上.更一般地说,有一个收益递减法则,它将演变为"规模​​不经济"; 最终,添加另一个线程会导致程序运行速度比没有使用该线程时慢.是的,ThreadPool为您处理最大线程,但这可能是您在自己的算法中实现自己的各种功能中最简单的.

  • 确保每个线程的工作都已优化.寻找天真或低效的算法(我称之为" O(我的上帝) - 复杂性")并简化它们.大多数操作的效率有一个下限(它因操作类型而异),"过早优化是万恶之源"(不要以牺牲代码实际工作为代价来优化性能),但是了解在多线程环境中,运行一次算法对算法效率的任何增益都会乘以运行它的次数,因此确保并行操作是有效的双重奖励.