【发布时间】:2010-12-29 20:01:20
【问题描述】:
将执行给定任务的并发线程数限制为等于主机系统上的处理器数有什么好处?或者更好地信任诸如 .NET 的 ThreadPool 之类的库来做正确的事情……即使在任何给定时刻有 25 个不同的并发线程发生?
【问题讨论】:
标签: c# performance concurrency multithreading threadpool
将执行给定任务的并发线程数限制为等于主机系统上的处理器数有什么好处?或者更好地信任诸如 .NET 的 ThreadPool 之类的库来做正确的事情……即使在任何给定时刻有 25 个不同的并发线程发生?
【问题讨论】:
标签: c# performance concurrency multithreading threadpool
大多数线程不受 CPU 限制,它们最终会等待 IO 或其他事件。如果您现在查看您的系统,我想您有 100 个(如果不是 1000 个)线程执行没有问题。按照这个标准,您最好离开 .NET 线程池去做正确的事情!
但是,如果线程都受 CPU 限制(例如,像光线追踪之类的东西),那么最好将线程数限制为内核数,否则上下文切换可能会开始损害性能。
【讨论】:
好吧,如果您的瓶颈只有处理器,那么它可能是有道理的,但这会忽略所有内存和其他 i/o 瓶颈,并且至少您的缓存内存可能会引发页面错误和其他会减慢速度的事件线程。
我自己相信图书馆。线程等待各种各样的事情,你不希望你的应用程序因为它不能产生一个新线程而变慢,即使其余的大部分只是在休眠,等待一些事件或资源。
【讨论】:
线程池在这方面已经做得相当不错了。它试图将正在运行的线程数限制为机器中的 CPU 内核数。当一个线程结束时,它会立即安排另一个符合条件的线程执行。
每 0.5 秒,它会评估正在运行的线程的情况。当线程运行时间过长时,它假定它们已停止并允许另一个线程开始执行。您现在运行的线程数将超过 CPU 内核数。这可以达到允许的最大线程数,由 ThreadPool.SetMaxThreads() 设置。
从 .NET 2.0 SP1 开始,默认的最大线程数显着增加到内核数的 250 倍。你永远不应该到达那里。如果这样做,您将浪费大约 2 分钟的时间来运行可能不是最佳数量的线程。然而,这些线程都必须阻塞那么长时间,而不是线程的典型执行模式。另一方面,如果这些线程都在等待同一种资源,它们很可能只是轮流进行,添加更多线程并不能提高吞吐量。
长话短说,如果您运行的线程执行速度很快(最多几秒钟)并且不会长时间阻塞,那么线程池将运行良好。当您的代码与该模式不匹配时,您可能应该考虑创建自己的 Thread 对象。
【讨论】:
在各种线程:处理器比率下衡量您的应用程序。根据有关您的应用程序的硬数据得出结论。不接受来自第一原则的关于您应该获得什么性能的争论,只有您做了什么才重要。
【讨论】: