27

在 Java 中,是否有一种编程方式来找出 CPU 支持多少并发线程?

更新

澄清一下,我不是想用线程敲击 CPU,而且我知道 Runtime.getRuntime().availableProcessors() 函数,它为我提供了我正在寻找的部分信息。

我想知道是否有办法自动调整线程池的大小,以便:

  • 如果我在使用了 1 年的服务器上运行,我会得到 2 个线程(每个 CPU 1 个线程 x 任意乘数 2)
  • 如果我从现在开始两年后切换到 Intel i7 四核(每个内核支持 2 个线程),我将获得 16 个线程(每个 CPU 2 个逻辑线程 x 4 个 CPU x 2 的任意乘数)。
  • 相反,如果我使用八核 Ultrasparc T2 服务器(每个内核支持 8 个线程),我得到 128 个线程(每个 CPU 8 个线程 x 8 个 CPU x 2 的任意乘数)
  • 如果我在由 30 台不同机器组成的集群上部署相同的软件,这些机器可能在不同年份购买,我不需要阅读 CPU 规格并为每台机器设置配置选项。
4

7 回答 7

28

Runtime.availableProcessors 返回逻辑处理器(即硬件线程)的数量,而不是物理内核。参见CR 5048379

于 2008-10-19T07:07:22.903 回答
21

单个非超线程 CPU 内核始终可以运行一个线程。您可以生成大量线程,CPU 将在它们之间切换。

最佳数量取决于任务。如果这是一项需要大量 CPU 资源且不需要任何 I/O(例如计算 pi、素数等)的任务,那么每个 CPU 1 个线程可能是最好的。如果任务受更多 I/O 限制。就像从磁盘处理信息一样,那么每个 CPU 拥有多个线程可能会获得更好的性能。在这种情况下,可以在 CPU 处理来自先前磁盘读取的信息时进行磁盘访问。

我建议您对您的情况下的性能如何随每个 CPU 内核的线程数进行扩展测试,并据此做出决定。然后,当您的应用程序运行时,它可以检查availableProcessors()并决定它应该产生多少线程。超线程将使单核对操作系统和所有应用程序(包括 2 个 CPU)显示availableProcessors()为 2 个 CPU,因此如果您的应用程序可以使用超线程,您将获得好处。如果不是,那么性能会受到轻微影响,但可能不足以让额外的努力来满足它的价值。

于 2008-10-18T16:48:35.803 回答
4

没有标准的方法来获取 Java 中每个 CPU 内核支持的线程数。最好的办法是获取一个 Java CPUID 实用程序,它可以为您提供处理器信息,然后将其与您必须生成的表进行匹配,该表为您提供处理器管理的每个内核的线程,而无需“真正的”上下文切换。

于 2008-10-18T21:53:00.277 回答
2

每个处理器或处理器内核一次只能做一件事。使用超线程,情况会有所不同,但在大多数情况下仍然如此,这就是为什么我的 HT 机器在工作中几乎从未超过 50%,即使它达到 100%,它也不会一次处理两倍.

您可能只需要对计划部署的常见架构进行一些测试,以确定您希望在每个 CPU 上运行多少线程。如果您正在等待大量 I/O,那么仅使用 1 个线程可能会太慢。运行大量线程会减慢速度,因为处理器必须更频繁地切换线程,这可能会非常昂贵。我不确定您可以运行多少线程是否有任何硬编码限制,但我保证在您达到任何硬​​限制之前,您的应用程序可能会因过多的线程切换而陷入困境。最终,您应该将其作为一个选项保留在配置文件中,以便您可以轻松地将应用程序调整到运行它的任何处理器。

于 2008-10-18T17:42:54.430 回答
1

CPU 通常不会限制线程数,而且我认为 Java 本身不会限制它将产生的本机(内核)线程数。

Runtime 类中有一个方法availableProcessors()。那是你要找的吗?

于 2008-10-18T16:42:58.793 回答
1

基础知识:加载到内存中的应用程序是一个进程。一个进程至少有 1 个线程。如果需要,您可以在一个进程中创建任意数量的线程(理论上)。所以线程的数量取决于你和你使用的算法。

如果您使用线程池,则意味着线程池管理线程数,因为创建线程会消耗资源。线程池回收线程。这意味着许多逻辑线程可以一个接一个地在一个物理线程中运行。

您不必考虑线程数,它由线程池算法管理。线程池为服务器和台式机 (OS) 选择不同的算法。

Edit1:如果您认为线程池不使用您拥有的资源, 您可以使用显式线程。在这种情况下,您可以显式管理线程数。

于 2008-10-18T17:34:22.700 回答
0

这是 VM 的功能,而不是 CPU。它与每个线程消耗的堆数量有关。当堆上的空间用完时,就完成了。与其他海报一样,如果由于线程数超过堆空间,我怀疑您的应用程序在此之前将无法使用。

请参阅此讨论

于 2008-10-18T16:50:38.500 回答