当决定线程池大小时,如何考虑超线程技术?

9
我已阅读多个关于如何决定线程池大小的问题和文章。这些问题包括: 文章包括: 然而,这些都没有直接解决超线程Intel芯片上的问题。
在启用超线程的计算机上,当决定线程池大小时,我应该考虑虚拟核心吗?
例如,在Java Concurrency In Practice一书中,Brian Goetz建议对于CPU密集型应用程序,通常可以考虑使用(# of cores + 1)作为线程数。对于一个带有4个真实核心和8个虚拟(超线程)核心的Intel Core i7芯片,该公式应该是(4 + 1)还是(8 + 1)
此外,应用程序的性质在如何考虑超线程核心方面有多大的差异?
与上面提到的相反,我的应用程序不是CPU受限的。相反,我的应用程序是一个服务器端Vaadin应用程序,其中线程通过JDBC每分钟多次进行Internet连接并访问本地数据库。鉴于超线程基本上是附加到同一核心的第二组寄存器,也许一个CPU受限的应用程序应该考虑仅使用真实核心,而一个网络/IO受限的应用程序应该考虑虚拟核心?
最后,英特尔芯片的类型是否会影响超线程,从而影响线程池大小的计算?具体而言,XeonCore i7/i5之间在这个问题上是否有区别?例如,当前的MacBook(Core i7)和Mac Pro(Xeon)之间的区别。
我意识到涉及许多变量,这是一个复杂的话题。没有完全精确的答案。我只是希望得到一些通用规则和建议,以帮助像我这样对此类硬件问题不太熟悉的程序员。

一个网络绑定的应用程序并不会从更多的线程中受益,它只应该选择处理意外页面故障或可以有用地挂起多少I/O所需的数量。对于一个不受CPU限制的应用程序来说,CPU几乎是无关紧要的。 - David Schwartz
1
@DavidSchwartz,这是一个相当广泛的说法,我认为一般来说,当你面临外部延迟(即内存、网络等)时,你拥有的线程越多,你可以完成的工作就越多,假设你的应用程序可以并行化其工作。HT 可以通过增加有效核心数而无需进行上下文切换来帮助实现这一点。当然,你还需要考虑缓存问题,这篇论文讨论了权衡 - http://ieeexplore.ieee.org/xpl/login.jsp?tp=&arnumber=4906237&url=http%3A%2F%2Fieeexplore.ieee.org%2Fxpls%2Fabs_all.jsp%3Farnumber%3D4906237 - Leeor
针对性能问题,第一步总是要进行分析 - Nicu Stiurca
你的应用程序不需要也不值得付出努力去考虑真正的核心或超线程核心是否有益,因为它1/不受CPU限制;2/由Java VM实现抽象化;3/取决于框架的效率;4/更有可能是数据库在框架内运行的Java代码之前面临瓶颈。 - Ken Cheung
1个回答

3
如何在决定线程池大小时考虑超线程?
短而言之,不要考虑。
更长的答案是,Goetz的“公式”实际上只是一个经验法则。这里使用的语言"通常情况下,对于CPU密集型应用程序,人们可能会将(核心数+1)作为线程数量"使这一点清楚。那个“经验法则”数字可能会给您带来次优的性能,原因有很多。
正确的方法是:
1.选择一个数字 2.测量性能 3.调整数字并转至步骤2。
直到您找到适合您的用例的线程池大小为止。(大约)给出最佳答案。
另一个需要注意的事项是,在构建基于服务器的系统时,性能只是众多考虑因素之一。另一个考虑因素是如何在极端负载下运行您的系统。如果您根据“最佳情况”工作负载优化性能而不考虑过载情况下的行为,那么如果出现问题,您可能会遇到严重的问题。
仅针对最大吞吐量进行优化可能会产生不良后果...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接