Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Runtime.availableProcessors: what is it going to return?

Tags:

java

The javadoc for Runtime.availableProcessors() in Java 1.6 is delightfully unspecific. Is it looking just at the hardware configuration, or also at the load? Is it smart enough to avoid being fooled by hyperthreading? Does it respect a limited set of processors via the linux taskset command?

I can add one datapoint of my own: on a computer here with 12 cores and hyperthreading, Runtime.availableProcessors() indeed returns 24, which is not a good number to use in deciding how many threads to try to run. The machine was clearly not dead-idle, so it also can't have been looking at load in any effective way.

like image 833
bmargulies Avatar asked Feb 23 '12 22:02

bmargulies


2 Answers

On Windows, GetSystemInfo is used and dwNumberOfProcessors from the returned SYSTEM_INFO structure.

This can be seen from void os::win32::initialize_system_info() and int os::active_processor_count() in os_windows.cpp of the OpenJDK source code.

dwNumberOfProcessors, from the MSDN documentation says that it reports 'The number of logical processors in the current group', which means that hyperthreading will increase the number of CPUs reported.

On Linux, os::active_processor_count() uses sysconf:

int os::active_processor_count() {
  // Linux doesn't yet have a (official) notion of processor sets,
  // so just return the number of online processors.
  int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);
  assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check");
  return online_cpus;
}

Where _SC_NPROCESSORS_ONLN documentation says 'The number of processors currently online (available).' This is not affected by the affinity of the process, and is also affected by hyperthreading.

like image 129
prunge Avatar answered Sep 18 '22 11:09

prunge


According to Sun Bug 6673124:

The code for active_processor_count, used by Runtime.availableProcessors() is as follows:

int os::active_processor_count() {
  int online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
  pid_t pid = getpid();
  psetid_t pset = PS_NONE;
  // Are we running in a processor set?
  if (pset_bind(PS_QUERY, P_PID, pid, &pset) == 0) {
    if (pset != PS_NONE) {
      uint_t pset_cpus;
      // Query number of cpus in processor set
      if (pset_info(pset, NULL, &pset_cpus, NULL) == 0) {
    assert(pset_cpus > 0 && pset_cpus <= online_cpus, "sanity check");
    _processors_online = pset_cpus;
    return pset_cpus;
      }
    }
  }
  // Otherwise return number of online cpus
  return online_cpus;
}

This particular code may be Solaris-specific. But I would imagine that the behavior would be at least somewhat similar on other platforms.

like image 20
Daniel Pryden Avatar answered Sep 18 '22 11:09

Daniel Pryden