1

I need to get the number of avaible CPU threads on a machine. Previously I used Runtime.getRuntime().availableProcessors() to determine that and it works just fine for my PC at home. It returns 16 in my case (cause I got a 8 core, 16 thread processor). Now I wanted to use that application on a server that has a dual socket configuration, two Xeon Gold 6154 with 18 cores/36 threads each. The way I used to determine the amount of threads now gives me 36 instead of 72.

It seems like the avaibleProcessors() method does not respect dual socket configurations.

What I found with some research is java.util.concurrent.ForkJoinPool.commonPool(), that should work with dualsocket configurations. However, on my local PC it returns java.util.concurrent.ForkJoinPool@61e717c2[Running, parallelism = 15, size = 0, active = 0, running = 0, steals = 0, tasks = 0, submissions = 0] aka one thread is missing... Is that normal? Do I have to do some math and add 1 to the number? The output is not that well formatted either, I would have to do some Regex or similar to get that to a usable format.

Are there better ways to determine the amount of threads on a machine? Or do I have to stick with the commonPool() method for now?

2 Answers2

1

By default ForkJoinPool.commonPool() will have availableProcessors() - 1 threads if availableProcessors() > 1, and 1 thread otherwise.

This is part of the source code from ForkJoinPool.java:

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

as you can see it assigns Runtime.getRuntime().availableProcessors() - 1 to parallelism. So, if you have 16 cores, parallelism will be equal to 15.

availableProcessors() is how many cores are available to the jvm, so I guess, your jvm is running on only 1 cpu of your dual socket xeon. I don't know how to make it run on 2 CPUs though.

Why does this Java code not utilize all CPU cores? the answer by johnidis in this thread suggests that you run your JVM in the client mode, that's why you use only one CPU, try running it with -server flag, let me know if this fixes your problem.

EDIT: I researched this a little more and this link https://docs.oracle.com/javase/7/docs/technotes/guides/vm/server-class.html suggests that if you have java 5 or later, then the -server option does not need to be passed. However, maybe your process was launched with the -client option?

Also this thread Runtime#availableProcessors() doesn't return correct result on Linux server suggests that you jvm can be limited to however many processors are specified in /proc/cpuinfo if you're on linux.

Coder-Man
  • 2,391
  • 3
  • 11
  • 19
0

The number of processors returned by Runtime.getRuntime().availableProcessors() is the number of processors reported by the operating system. It is a valid number to use from Java. From experience, availableProcessors() does support dual socket architectures. If the number is not what you are expecting, then you will need to look into the configuration and capability of the JVM, OS and BIOS that you are running upon. Specifically look into how the OS that you are using reports available CPU count to its processes.

A bit of history that may help you. Hyper threading, as you may know is not a true extra CPU. It is essentially timesharing a single CPU that has a decent amount of support for parallel operations; which may or may not give a performance boost for different types of work load. The fastest way for many operating systems to add support for hyper threading was to report them as extra CPUs; however that is not the only way that it could have been done. If hyper threading support is turned off at the bios or OS level then the CPU count is often affected.

Chris K
  • 11,622
  • 1
  • 36
  • 49
  • Task manager reports: Sockets:2, Cores: 36, Threads: 72. And I know about how Hyper Threading works, the java application functions as a wrapper to start a rendering application (wich benefit from hyperthreading) and I need to parse the amount of avaible threads with it – Mining_Pickaxe Jul 07 '18 at 14:25
  • @Mining_Pickaxe what OS and version, is it containerised (if so versions and config), what version of Java, is the OS configured to pin processes to threads.. You will need to do quite a lot more digging to understand and influence this behaviour. Just know that availableProcessors is the correct method to be calling. If you are unhappy with its return value, and want the ability to experiment with different values then consider adding a config override at the point where you are allocating the number of threads to create. Then you can tune the thread count per environment. – Chris K Jul 07 '18 at 14:59