处理器核心数与线程池大小的比较 [英] Number of processor core vs the size of a thread pool

查看:105
本文介绍了处理器核心数与线程池大小的比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我多次听说最好将线程池中的线程数保持在该系统中的核心数之下。拥有两次或更多线程而不是内核数量不仅浪费,而且还可能导致性能下降。

Many times I've heard that it is better to maintain the number of threads in a thread pool below the number of cores in that system. Having twice or more threads than the number of cores is not only a waste, but also could cause performance degradation.

这些是真的吗?如果没有,揭穿这些主张的基本原则是什么(特别是与java有关)?

Are those true? If not, what are the fundamental principles that debunk those claims (specifically relating to java)?

推荐答案

声称不是真的作为一般性陈述。也就是说,有时候它们是真的(或者是真实的),有时候它们显然是假的。

The claims are not true as a general statement. That is to say, sometimes they are true (or true-ish) and other times they are patently false.

有几件事无可争辩地是真的:

A couple things are indisputably true:


  1. 更多线程意味着更多的内存使用量。每个线程都需要一个线程堆栈。对于最近的HotSpot JVM,最小线程堆栈大小为64Kb,默认值可以高达1Mb。这可能很重要。此外,任何活动的线程都可能拥有或共享堆中的对象,无论它是否当前是可运行的。因此,期望更多线程意味着更大的内存工作集是合理的。

  1. More threads means more memory usage. Each thread requires a thread stack. For recent HotSpot JVMs, the minimum thread stack size is 64Kb, and the default can be as much as 1Mb. That can be significant. In addition, any thread that is alive is likely to own or share objects in the heap whether or not it is currently runnable. Therefore is is reasonable to expect that more threads means a larger memory working set.

JVM实际上没有比核心(或超线程核心)更多的线程运行或者其他)在执行硬件上。如果没有引擎,汽车将无法运行,如果没有核心,线程将无法运行。

A JVM cannot have more threads actually running than there are cores (or hyperthread cores or whatever) on the execution hardware. A car won't run without an engine, and a thread won't run without a core.

除此之外事情变得不那么明确。 问题是活动线程可以处于各种状态。例如:

Beyond that, things get less clear cut. The "problem" is that a live thread can in a variety of "states". For instance:


  • 活动线程可以正在运行;即积极执行指令。

  • 活动线程可以运行;即等待核心以便它可以运行。

  • 一个活动线程可以通过同步;即等待来自另一个线程的信号,或等待锁被释放。

  • 活动线程可以等待外部事件;例如等待一些外部服务器/服务响应请求。

  • A live thread can be running; i.e. actively executing instructions.
  • A live thread can be runnable; i.e. waiting for a core so that it can be run.
  • A live thread can by synchronizing; i.e. waiting for a signal from another thread, or waiting for a lock to be released.
  • A live thread can be waiting on an external event; e.g. waiting for some external server / service to respond to a request.

每个核心一个线程启发式假定线程正在运行或者可以运行(根据以上所述)。但是对于很多多线程应用程序来说,启发式是错误的...因为它没有考虑其他状态中的线程。

The "one thread per core" heuristic assumes that threads are either running or runnable (according to the above). But for a lot of multi-threaded applications, the heuristic is wrong ... because it doesn't take account of threads in the other states.

现在太多了 线程明显可以导致显着的性能下降,使用太多内存很简单。 (想象一下,你有4Gb的物理内存,你可以用1Mb堆栈创建8,000个线程。这是虚拟内存抖动的一个秘诀。)

Now "too many" threads clearly can cause significant performance degradation, simple by using too much memory. (Imagine that you have 4Gb of physical memory and you create 8,000 threads with 1Mb stacks. That is a recipe for virtual memory thrashing.)

但是其他什么呢?可能有太多线程导致过多的上下文切换?

But what about other things? Can having too many threads cause excessive context switching?

我不这么认为。如果您有很多线程,并且您的应用程序使用这些线程可能导致过多的上下文切换,并且 对性能不利。但是,我认为上下文切换的根本原因不是实际的线程数。性能问题的根源更可能是应用程序:

I don't think so. If you have lots of threads, and your application's use of those threads can result in excessive context switches, and that is bad for performance. However, I posit that the root cause of the context switched is not the actual number of threads. The root of the performance problems are more likely that the application is:


  • 以特别浪费的方式同步;例如使用 Object.notifyAll() Object.notify()会更好,或者

  • 在高度竞争的数据结构上进行同步,或者

  • 相对于每个线程正在执行的有用工作量进行太多同步,或者

  • 尝试并行执行太多I / O.

  • synchronizing in a particularly wasteful way; e.g. using Object.notifyAll() when Object.notify() would be better, OR
  • synchronizing on a highly contended data structure, OR
  • doing too much synchronization relative to the amount of useful work that each thread is doing, OR
  • trying to do too much I/O in parallel.

(在最后一种情况下,瓶颈很可能是I / O系统而不是上下文切换...除非I / O是IPC与同一台机器上的服务/程序。)

(In the last case, the bottleneck is likely to be the I/O system rather than context switches ... unless the I/O is IPC with services / programs on the same machine.)

另一点是在如果没有上述混淆因素,拥有更多线程不会增加上下文切换。如果你的应用程序有N个可运行的线程竞争M个处理器,并且线程纯粹是计算和无争用的,那么OS'线程调度器将尝试在它们之间进行时间分片。但是,时间片的长度很可能以十分之一秒(或更长)来衡量,因此与CPU绑定线程在其切片期间实际执行的工作相比,上下文切换开销可以忽略不计。如果我们假设时间片的长度是常数,那么上下文切换开销也将是常量。添加更多可运行的线程(增加N)不会显着改变工作与开销的比率。

The other point is that in the absence of the confounding factors above, having more threads is not going to increase context switches. If your application has N runnable threads competing for M processors, and the threads are purely computational and contention free, then the OS'es thread scheduler is going to attempt to time-slice between them. But the length of a timeslice is likely to be measured in tenths of a second (or more), so that the context switch overhead is negligible compared with the work that a CPU-bound thread actually performs during its slice. And if we assume that the length of a time slice is constant, then the context switch overhead will be constant too. Adding more runnable threads (increasing N) won't change the ratio of work to overhead significantly.

总之,它确实太多线程对性能有害。然而,实际上有多少太多并没有很好的通用经验法则。并且(幸运的是)在性能问题变得显着之前,您通常会有相当大的余地。

In summary, it is true that "too many threads" is harmful for performance. However, there is no good universal "rule of thumb" for how many "too many" actually is. And (fortunately) you generally have considerable leeway before the performance problems become significant.

这篇关于处理器核心数与线程池大小的比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆