获取双套接字服务器上的可用线程数

时间:2018-07-07 09:44:05

标签: java hardware

我需要获取计算机上可用的CPU线程数。 以前,我使用Runtime.getRuntime().availableProcessors()来确定这一点,并且它对于我在家中的PC都可以正常工作。在我的情况下,它返回16(因为我有一个8核,16线程处理器)。 现在,我想在具有双插槽配置的服务器上使用该应用程序,两个Xeon Gold 6154具有18个内核/ 36个线程。我以前用来确定线程数量的方法现在给了我36而不是72

似乎avaibleProcessors()方法不支持双套接字配置。

我在一些研究中发现的是java.util.concurrent.ForkJoinPool.commonPool(),它应该适用于双插槽配置。但是,在我的本地PC上,它返回java.util.concurrent.ForkJoinPool@61e717c2[Running, parallelism = 15, size = 0, active = 0, running = 0, steals = 0, tasks = 0, submissions = 0],也就是缺少一个线程……这正常吗?我需要做一些数学运算并将数字加1吗?输出的格式也不正确,我必须做一些正则表达式或类似的操作才能将其转换为可用的格式。

是否有更好的方法来确定计算机上的线程数量?还是我现在必须坚持使用commonPool()方法?

2 个答案:

答案 0 :(得分:1)

默认情况下,如果ForkJoinPool.commonPool()> 1,availableProcessors() - 1将具有availableProcessors()个线程,否则将具有1个线程。

这是ForkJoinPool.java的源代码的一部分:

if (parallelism < 0 && // default 1 less than #cores
   (parallelism = Runtime.getRuntime().availableProcessors() - 1) <= 0)
        parallelism = 1;
如您所见,

它将Runtime.getRuntime().availableProcessors() - 1分配给parallelism。因此,如果您有16个核心,则parallelism将等于15

availableProcessors()是jvm可以使用多少个内核,所以我想您的jvm仅在双插槽xeon的1 cpu上运行。我不知道如何使它在2个CPU上运行。

Why does this Java code not utilize all CPU cores?在这个线程中,johnidis的回答表明您在客户端模式下运行JVM,这就是为什么仅使用一个CPU,尝试使用-server标志运行它的原因,请告诉我解决您的问题。

编辑:我对此进行了更多研究,并且此链接https://docs.oracle.com/javase/7/docs/technotes/guides/vm/server-class.html建议,如果您使用的是Java 5或更高版本,则不需要传递-server选项。但是,也许您的过程是通过-client选项启动的?

此外,该线程Runtime#availableProcessors() doesn't return correct result on Linux server建议您将jvm限制为/proc/cpuinfo中指定的许多处理器(如果您使用的是Linux)。

答案 1 :(得分:0)

Runtime.getRuntime().availableProcessors()返回的处理器数是操作系统报告的处理器数。这是从Java使用的有效数字。根据经验,availableProcessors()确实支持双套接字体系结构。如果该数目不是您所期望的,那么您将需要研究正在运行的JVM,OS和BIOS的配置和功能。专门研究正在使用的OS如何将可用CPU计数报告给其进程。

一些历史可以为您提供帮助。您可能知道,超线程并不是真正的额外CPU。从本质上讲,它是在分时共享单个CPU,该CPU对并行操作提供了不错的支持。对于不同类型的工作负载,这可能会或可能不会提高性能。许多操作系统增加对超线程支持的最快方法是将它们报告为额外的CPU。但是,这并不是本可以完成的唯一方法。如果在BIOS或OS级别上关闭了超线程支持,那么CPU数量通常会受到影响。