我和一个朋友正在讨论线程池中的线程数量应该是处理器计数+1还是仅仅是处理器计数。
我选择只使用处理器计数,因为可以将偶数个线程分配给每个处理器,而他选择处理器计数+1,因为他认为这可以帮助他优化性能。
谁是正确的?
发布于 2010-02-11 12:37:13
你们两个都不行。
正确的答案是:您需要大量的线程来产生最佳的整体结果。
您添加的每个线程都有成本。这是一个很小的成本,但这绝对是一个成本。将30,000个线程放入一个线程池中,然后看着您的系统逐渐停止(如果它们都在做一些事情)。
但每个线程在理论上为您节省了一些(总体)时间。
从概念上讲,您可以绘制这种关系,并生成一系列线程,在给定某些资源约束的情况下,这些线程将提供所需的结果。正确的线程数在该范围内的某个位置。
注:我说的是“总体结果”。这不一定是“最快的结果”。一个线程可以在10分钟内完成一项任务。100个线程可以在15秒内完成。1000个线程可能会在10秒内完成这一任务,因为您的特定问题正开始达到争用限制。这是一个更好的整体结果吗?10秒和15秒之间可能没有真正的区别,但1000个线程可能会使用更多的内存。
请记住,并不是所有的线程都是CPU受限的,所以在很多情况下,拥有比核心数量多得多的线程是非常有意义的,因为在执行任务的某个时刻,线程可能会在等待发生某些事情(网络通信、磁盘读取等)时休眠。
发布于 2010-02-11 12:38:50
都不是。
操作系统内核(除非通过亲和性设置明确指示)可以并将迁移系统中可用内核上的进程。
如果你看看微软公司( System.Threading.ThreadPool ),默认情况下,微软为每个可用核心创建250个线程。重用空闲线程比创建/销毁(清洗并重复)线程“更便宜”。
发布于 2010-02-11 15:48:35
如果您的所有线程都是CPU受限的,并且不执行I/O,那么您通常会在CPU数量完全相同的情况下获得最佳结果。运行超过CPU数量会导致频繁的上下文切换(这会减慢速度),运行较少会导致一些CPU闲置。
如果线程使用大量RAM,您可能需要少于CPU的数量,以避免进入交换空间。在并行编译C++代码时,经常会出现这种情况,因为GCC (否则会占用大量的CPU)会使用大量内存来实例化模板。
如果线程阻塞I/O (通常是到磁盘的,但也可能是网络或其他外部资源),您可能需要比CPU数量更多的CPU,以保持CPU的完全占用,但另一方面,您可能希望减少CPU数量,以避免I/O阻塞(尤其是当需要同时读/写多个位置时,机械HDD会变慢)。
如果系统有任何实时需求(例如游戏或视频播放器),您应该让一个CPU大部分时间处于空闲状态(以允许频繁的上下文切换和交互)。
因此,正如其他人所说,没有简单的答案。在上面的所有示例中,我假设系统上没有其他使用大量CPU的程序在运行(令人惊讶的是,这种情况最常见)。如果还有其他CPU用户,在计算中也要考虑到这一点(例如,通过减少可用CPU计数)。
对于大量CPU受限的情况,唯一有用的“快速规则”是N-1、N和N+1 (其中N是可用CPU的数量),具体取决于所提到的因素。对于严重的磁盘I/O限制情况,应该只使用一个线程(每个HDD)。
https://stackoverflow.com/questions/2242260
复制相似问题