class Concurrent::Utility::ProcessorCounter
@!visibility private
Public Class Methods
Source
# File lib/concurrent-ruby/concurrent/utility/processor_counter.rb, line 10 def initialize @processor_count = Delay.new { compute_processor_count } @physical_processor_count = Delay.new { compute_physical_processor_count } end
Public Instance Methods
Source
# File lib/concurrent-ruby/concurrent/utility/processor_counter.rb, line 73 def physical_processor_count @physical_processor_count.value end
Number of physical processor cores on the current system. For performance reasons the calculated value will be memoized on the first call.
On Windows the Win32 API will be queried for the ‘NumberOfCores from Win32_Processor`. This will return the total number “of cores for the current instance of the processor.” On Unix-like operating systems either the `hwprefs` or `sysctl` utility will be called in a subshell and the returned value will be used. In the rare case where none of these methods work or an exception is raised the function will simply return 1.
@return [Integer] number physical processor cores on the current system
@see github.com/grosser/parallel/blob/4fc8b89d08c7091fe0419ca8fba1ec3ce5a8d185/lib/parallel.rb
@see msdn.microsoft.com/en-us/library/aa394373(v=vs.85).aspx @see www.unix.com/man-page/osx/1/HWPREFS/ @see linux.die.net/man/8/sysctl
Source
# File lib/concurrent-ruby/concurrent/utility/processor_counter.rb, line 52 def processor_count @processor_count.value end
Number of processors seen by the OS and used for process scheduling. For performance reasons the calculated value will be memoized on the first call.
When running under JRuby the Java runtime call ‘java.lang.Runtime.getRuntime.availableProcessors` will be used. According to the Java documentation this “value may change during a particular invocation of the virtual machine… [applications] should therefore occasionally poll this property.” Subsequently the result will NOT be memoized under JRuby.
Ruby’s Etc.nprocessors will be used if available (MRI 2.2+).
On Windows the Win32 API will be queried for the ‘NumberOfLogicalProcessors from Win32_Processor`. This will return the total number “logical processors for the current instance of the processor”, which taked into account hyperthreading.
-
AIX: /usr/sbin/pmcycles (AIX 5+), /usr/sbin/lsdev
-
Alpha: /usr/bin/nproc (/proc/cpuinfo exists but cannot be used)
-
BSD: /sbin/sysctl
-
Cygwin: /proc/cpuinfo
-
Darwin: /usr/bin/hwprefs, /usr/sbin/sysctl
-
HP-UX: /usr/sbin/ioscan
-
IRIX: /usr/sbin/sysconf
-
Linux: /proc/cpuinfo
-
Minix 3+: /proc/cpuinfo
-
Solaris: /usr/sbin/psrinfo
-
Tru64 UNIX: /usr/sbin/psrinfo
-
UnixWare: /usr/sbin/psrinfo
@return [Integer] number of processors seen by the OS or Java runtime
@see github.com/grosser/parallel/blob/4fc8b89d08c7091fe0419ca8fba1ec3ce5a8d185/lib/parallel.rb
@see docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#availableProcessors() @see msdn.microsoft.com/en-us/library/aa394373(v=vs.85).aspx
Private Instance Methods
Source
# File lib/concurrent-ruby/concurrent/utility/processor_counter.rb, line 120 def compute_physical_processor_count ppc = case RbConfig::CONFIG["target_os"] when /darwin1/ IO.popen("/usr/sbin/sysctl -n hw.physicalcpu", &:read).to_i when /linux/ cores = {} # unique physical ID / core ID combinations phy = 0 IO.read("/proc/cpuinfo").scan(/^physical id.*|^core id.*/) do |ln| if ln.start_with?("physical") phy = ln[/\d+/] elsif ln.start_with?("core") cid = phy + ":" + ln[/\d+/] cores[cid] = true if not cores[cid] end end cores.count when /mswin|mingw/ require 'win32ole' result_set = WIN32OLE.connect("winmgmts://").ExecQuery( "select NumberOfCores from Win32_Processor") result_set.to_enum.collect(&:NumberOfCores).reduce(:+) else processor_count end # fall back to logical count if physical info is invalid ppc > 0 ? ppc : processor_count rescue return 1 end
Source
# File lib/concurrent-ruby/concurrent/utility/processor_counter.rb, line 79 def compute_processor_count if Concurrent.on_jruby? java.lang.Runtime.getRuntime.availableProcessors elsif Etc.respond_to?(:nprocessors) && (nprocessor = Etc.nprocessors rescue nil) nprocessor else os_name = RbConfig::CONFIG["target_os"] if os_name =~ /mingw|mswin/ require 'win32ole' result = WIN32OLE.connect("winmgmts://").ExecQuery( "select NumberOfLogicalProcessors from Win32_Processor") result.to_enum.collect(&:NumberOfLogicalProcessors).reduce(:+) elsif File.readable?("/proc/cpuinfo") && (cpuinfo_count = IO.read("/proc/cpuinfo").scan(/^processor/).size) > 0 cpuinfo_count elsif File.executable?("/usr/bin/nproc") IO.popen("/usr/bin/nproc --all", &:read).to_i elsif File.executable?("/usr/bin/hwprefs") IO.popen("/usr/bin/hwprefs thread_count", &:read).to_i elsif File.executable?("/usr/sbin/psrinfo") IO.popen("/usr/sbin/psrinfo", &:read).scan(/^.*on-*line/).size elsif File.executable?("/usr/sbin/ioscan") IO.popen("/usr/sbin/ioscan -kC processor", &:read).scan(/^.*processor/).size elsif File.executable?("/usr/sbin/pmcycles") IO.popen("/usr/sbin/pmcycles -m", &:read).count("\n") elsif File.executable?("/usr/sbin/lsdev") IO.popen("/usr/sbin/lsdev -Cc processor -S 1", &:read).count("\n") elsif File.executable?("/usr/sbin/sysconf") and os_name =~ /irix/i IO.popen("/usr/sbin/sysconf NPROC_ONLN", &:read).to_i elsif File.executable?("/usr/sbin/sysctl") IO.popen("/usr/sbin/sysctl -n hw.ncpu", &:read).to_i elsif File.executable?("/sbin/sysctl") IO.popen("/sbin/sysctl -n hw.ncpu", &:read).to_i else # TODO (pitr-ch 05-Nov-2016): warn about failures 1 end end rescue return 1 end