这要取决于硬件,因为您(可能)不是使用理论计算机而是物理硬件,因此您的资源是有限的。
此外,即使您可以运行5000多个线程,根据您的硬件配置,与10个线程等效程序相比,速度可能会慢得多。我认为您应该查看线程池。
当运行大量任务时,一个相当不错的经验法则是运行与你的物理核心数量相同的任务。
是的,你可以运行更多的任务,但它们会等待资源(或者在线程池中的线程)和你的计算机(无论大小)由于后台/其他进程的缘故不能将所有CPU核心资源100%地分配给线程。因此,实例化的任务越多,创建的线程越多,超过实际可能的并发线程数(每个核心1个),就会出现越来越多的资源管理、排队和交换。
我们在我现在工作的地方进行了一个测试,使用病毒样式启动额外的任务,发现最佳设置与CPU数量几乎相同。按照与物理核心数量一对一的比例启动的任务需要约1分钟才能完成。如果设置为双倍CPU数量,则任务完成时间从平均1分钟增加到平均5分钟。初始化超过核心计数的任务越多,速度下降的越快。
因此,例如,如果你有8个物理核心,那么8个任务(并且使用TPL,在活动进程中实质上有8个并发线程)应该是最快的。有主线程或进程创建其他任务以及其他后台进程,但如果计算机对于你的资源利用乐趣而言相当独立,那么它们将非常少。
基于核心计数编程任务上限的好处是,当你在不同大小的计算机上部署应用程序时,它会自动调整。
为了通过编程确定这一点,我们使用
var CoreCount = System.Environment.ProcessorCount / 2;
你问为什么要除以二?因为几乎所有现代处理器都使用逻辑核心或超线程。你应该发现,如果使用逻辑计数,每个任务的总体速度以及整个过程都会显著降低。物理核心才是关键。我们找不到快速找到物理与逻辑核心的方法,但对我们的盒子进行快速调查发现这是始终如一的。你的情况可能有所不同,但这可以让你快速上手。
每个线程都会消耗更多的内存(内核栈、线程环境块、线程本地、堆栈等)。据我所知,在Windows中没有明确的限制,因此约束将是内存(可能是每个线程的堆栈)。
在Linux中,线程更像进程(具有共享内存),您受到以下约束:
cat /proc/sys/kernel/threads-max
根据我的经验,在使用线程时,对于 CPU 密集型进程增加性能的一个好的经验法则是使用与核心数量相等的线程,但在超线程系统中,应该使用两倍的核心数。另一个可以得出的经验法则是针对 I/O 密集型进程。这个规则是将每个核心的线程数增加到四倍,但在超线程系统中,则可以将每个核心的线程数增加到四倍。