在决定线程池大小时如何看待超线程?

Bas*_*que 5 java multithreading hyperthreading threadpool

我已经阅读了几个关于如何决定线程池大小的问题和文章.问题包括:

文章包括:

但是,这些都没有直接解决英特尔芯片上的超线程问题.

在启用了超线程的计算机上,在决定线程池大小时是否应该考虑虚拟内核?

以Brian Goetz在Java Concurrency In Practice一书中提出的建议为例,一般来说,对于一个可以考虑( # of cores + 1 )用作线程数的CPU绑定应用程序.对于具有4个真实内核和8个虚拟(超线程)内核的英特尔酷睿i7芯片,该公式是( 4 + 1 )或者( 8 + 1 )?

此外,应用程序的性质在如何考虑超线程核心方面有多大差异?

与上面提到的相反,我自己的应用程序不受CPU限制.相反,我的应用程序是服务器端Vaadin应用程序,其中线程正在建立Internet连接并通过JDBC访问本地数据库,每分钟几次.鉴于超线程基本上是连接到同一核心的第二组寄存器,也许一个受CPU限制的应用程序应该只考虑真正的核心而网络/ IO绑定的应用程序应该考虑虚拟核心?

最后,英特尔芯片的类型是否会影响超线程,从而影响线程池大小?具体来说,Xeon和Core i7/i5之间的这个问题是否存在差异?例如,当前MacBook(Core i7)和Mac Pro(Xeon)之间的差异.

我意识到涉及许多变量,这是一个复杂的主题.没有完全精确的答案是可能的.我只是在寻找一些通用的规则和建议,以帮助像我这样对这些硬件问题不那么精明的程序员.

Ste*_*n C 3

在决定线程池大小时如何考虑超线程?

简短的回答是不要。

更长的答案是,戈茨的“公式”实际上只是一个经验法则。这里使用的语言

... “一般来说,对于受 CPU 限制的应用程序,人们可能会考虑使用 (# of cores + 1) 作为线程数”

说得很清楚。有各种各样的原因可以解释为什么“经验法则”数字可能会给您带来次优的性能。

正确的做法是:

  1. 选择一个号码
  2. 衡量绩效
  3. 调整数字并转到步骤 2。

....直到您得到一个线程池大小,该大小可以大致为您的用例提供最佳答案。

另一件需要注意的事情是,当您构建基于服务器的系统时,性能只是众多考虑因素之一。另一个是您的系统在极端负载下的表现。如果您根据“最佳情况”工作负载优化性能,而不考虑过载情况下的行为,那么如果出现问题,您可能会遭受严重打击。

仅针对最大吞吐量进行优化可能会产生不良后果......