我已经阅读了几个关于如何决定线程池大小的问题和文章。问题包括:
文章包括:
但是,这些都没有直接解决Hyper-Threading芯片上Intel的问题。
在启用了超线程的计算机上,我应该在决定线程池大小时考虑虚拟核心吗?
例如Brian Goetz在Java Concurrency In Practice一书中的建议,一般来说,对于一个CPU绑定的应用程序,人们可能会考虑使用( # of cores + 1 )
作为线程数。对于具有4个真实内核和8个虚拟(超线程)内核的英特尔酷睿i7芯片,该公式是( 4 + 1 )
还是( 8 + 1 )
?
此外,应用程序的性质在如何考虑超线程核心方面有多大区别?
与上面提到的相反,我自己的应用程序不受CPU限制。相反,我的应用程序是一个服务器端Vaadin应用程序,其中线程正在建立Internet连接并通过JDBC访问本地数据库,每分钟几次。鉴于超线程基本上是连接到同一核心的第二组寄存器,可能一个受CPU限制的应用程序应该只考虑真正的核心而网络/ IO绑定的应用程序应该考虑虚拟核心?
最后,英特尔芯片的类型是否会影响超线程,从而计算线程池大小?具体而言,Xeon和Core i7/i5之间在此问题上存在差异吗?例如,当前MacBook(Core i7)和Mac Pro(Xeon)之间的差异。
我意识到涉及许多变量,这是一个复杂的主题。没有完全精确的答案是可能的。我只是在寻找一些通用的规则和建议,以帮助像我这样对这些硬件事务不了解的程序员。
答案 0 :(得分:3)
在决定线程池大小时如何看待超线程?
简短的回答是不要。
更长的答案是,Goetz的“公式”实际上只是一个经验法则。这里使用的语言
... “一般来说,对于受CPU限制的应用程序可以考虑使用(核心数量+ 1)作为线程数”
说清楚了。为什么“经验法则”数字可能会给你次优的性能有各种各样的原因。
正确的方法是:
....直到你到达一个线程池大小,为你的用例提供大致最好的答案。
另一点需要注意的是,当您构建基于服务器的系统时,性能只是众多考虑因素之一。另一个是您的系统在极端负载下的执行情况。如果您根据“最佳情况”工作负载优化性能而不考虑过载情况下的行为,那么如果出现问题,您可能会遇到令人讨厌的冲击。
单独优化 以获得最大吞吐量会产生不良后果......