高效线程数量

8

我想要优化我的应用程序线程数量。 几乎所有线程在除了CPU使用率相等的情况下都有IO操作。 当系统中没有其他应用程序运行时,最有效的线程数量是多少。 我想知道Windows和JVM下的答案。

6个回答

13

没有通用的适用于所有操作系统的答案。这将取决于您的代码执行的具体任务集。您应该使用不同的配置对应用程序进行基准测试,以查看哪个配置性能最佳。

关于多线程的一些普遍提示:

  • 您无法通过增加线程来加速相似任务;例外情况是,如果您有多个 CPU,则可以使用一个线程并行计算任务,前提是此逻辑可以分割为不必须按顺序执行的部分。例如,归并排序问题是一个很好的例子,其中两个半部分可以按任意顺序排序。

  • 您可以通过将不使用机器的相同部分的任务并行化来实现一些加速。因此,考虑到您说您具有“相等价值”的 I/O 和计算任务,您将希望将它们分开成不同的线程 - 同样,这假定顺序不重要。

如果(与许多应用程序一样)线程执行某些计算逻辑,然后执行某些 I/O(例如将数据写入磁盘或数据库服务器),那么将非常难以想出某个公式来确定您应该拥有的确切线程数,因为这将高度依赖于您处理的数据,您如何处理它以及在处理完成后如何使用它。这就是为什么最好的方法是拥有一个可配置的线程池,其大小可以轻松调整 - 然后使用不同大小运行一些负载测试,并查看哪个性能最佳。


是的,您必须提供这些统计数据。这将是您的应用程序的独特之处。 - Andrew Coleson
当你说“例外情况是如果你有多个CPU”,你实际上是在谈论CPU还是CPU拥有的核心? - NathanOliver

10

Java Concurrency in Practice 这本书提供了一个优化线程池大小的粗略公式,以保持CPU处于特定的利用率:

N = CPU数量

U = 目标CPU利用率,0 <= U <= 1

W / C = 等待时间与计算时间的比率

保持处理器达到所需利用率的最佳线程池大小(线程数)为:

PoolSize = N * U * (1 + (W/C))

但这仅适用于CPU利用率。

您可以使用 Runtime.getRuntime().availableProcessors() 获取可用的处理器数量。


如果不知道具体要求,+1 这个经验法则可能是最好的。 - stacker

3

性能远非使用线程的唯一原因。

基本上,任何多线程程序都可以用一个更复杂的单线程模拟,所以实际上线程所做的是简化你的代码,并不一定使它更快。

尽管如此,如果你的应用程序可以利用多个核心或多个磁头同时运行,那么线程可以轻松地利用它。在这种情况下,你可能不需要比你拥有的分离核心或磁头更多的线程,因为进程切换具有明确的成本。


2

我认为这个问题没有一个明确的答案。我建议您尝试使用不同数量的线程来运行应用程序,看哪种方式表现最佳。其中一种方法是使用比硬件处理器线程数多一个的线程数进行测试,例如,如果您有一个每个核心一个线程的双核处理器,则可以使用3个线程。


1

我发现处理这个问题的最佳方式不是直接使用线程,而是使用Executor框架。您可以尝试不同的配置,但我发现我喜欢CallerRunsPolicy。


0

这个问题真的没有通用答案。你生成的线程数量取决于你正在执行多少任务,它们如何通信以及你如何设计应用程序。我有过非常大的应用程序,只有一个线程运行得很好。另一方面,我也有过为了性能而强制使用多个线程的小型应用程序。

(对不起,如果有任何拼写/格式问题,我是用手机打的)


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