我需要获取计算机上可用的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()方法?
答案 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数量通常会受到影响。