[ACCEPTED]-Detect number of CPUs installed-ruby
As of Ruby version 2.2.3, the
etc module in 8 Ruby's stdlib offers an
nprocessors method which returns 7 the number of processors. The caveat to 6 this, is that if ruby is relegated to a 5 subset of CPU cores,
Etc.nprocessors will only return the 4 number of cores that Ruby has access to. Also, as 3 seanlinsley pointed out, this will only return virtual 2 cores instead of physical cores, which may 1 result in a disparity in the expected value.
require 'etc' p Etc.nprocessors #=> 4
EDIT: Now rails ships with concurrent-ruby 9 as a dependency so it's probably the best 8 solution;
$ gem install concurrent-ruby $ irb irb(main):001:0> require 'concurrent' => true irb(main):002:0> Concurrent.processor_count => 8 irb(main):003:0> Concurrent.physical_processor_count => 4
see http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent.html for more info. Because it 7 does both physical and logical cores, it's 6 better than the inbuilt
and here is the 5 previous answer;
$ gem install facter $ irb irb(main):001:0> require 'facter' => true irb(main):002:0> puts Facter.value('processors')['count'] 4 => nil irb(main):003:0>
This facter gem is the best if you 4 want other facts about the system too, it's 3 not platform specific and designed to do 2 this exact thing.
UPDATE: updated to include 1 Nathan Kleyn's tip on the api change.
I am currently using this, which covers 1 all os. https://github.com/grosser/parallel/blob/master/lib/parallel.rb#L63
def self.processor_count case RbConfig::CONFIG['host_os'] when /darwin9/ `hwprefs cpu_count`.to_i when /darwin/ ((`which hwprefs` != '') ? `hwprefs thread_count` : `sysctl -n hw.ncpu`).to_i when /linux/ `cat /proc/cpuinfo | grep processor | wc -l`.to_i when /freebsd/ `sysctl -n hw.ncpu`.to_i when /mswin|mingw/ require 'win32ole' wmi = WIN32OLE.connect("winmgmts://") cpu = wmi.ExecQuery("select NumberOfCores from Win32_Processor") # TODO count hyper-threaded in this cpu.to_enum.first.NumberOfCores end end
with JRuby you can check it with the following 1 Java code:
Runtime runtime = Runtime.getRuntime(); int numberOfProcessors = runtime.availableProcessors();
Here is an implementation for Linux, OSX, Windows 1 and BSD: https://gist.github.com/1009994
module System extend self def cpu_count return Java::Java.lang.Runtime.getRuntime.availableProcessors if defined? Java::Java return File.read('/proc/cpuinfo').scan(/^processor\s*:/).size if File.exist? '/proc/cpuinfo' require 'win32ole' WIN32OLE.connect("winmgmts://").ExecQuery("select * from Win32_ComputerSystem").NumberOfProcessors rescue LoadError Integer `sysctl -n hw.ncpu 2>/dev/null` rescue 1 end end System.cpu_count # => 2
Surely if you can
cat it, you can open, read 5 and close it using the standard features 4 of the language without resorting to a
system()-type 3 call.
You may just need to detect what platform 2 you're on dynamically and either:
- use the
/proc/cpuinfo"file" for Linux; or
- communicate with WMI for Windows.
That last 1 line can use:
require 'win32ole' wmi = WIN32OLE.connect("winmgmts://") info = wmi.ExecQuery ("select * from Win32_ComputerSystem")
Then use info's NumberOfProcessors item.
I tried using
Facter but found it a bit slow. I 2 tried
system gem and found it a lot faster. It 1 is also very easy to use:
In linux you can also use
nproc, which is cleaner 4 that the other subshell-based solutions 3 here. I wanted vagrant to give the same 2 number of CPUs to the virtual machine as 1 the host has. I added this to
vb.cpus = `nproc`.to_i
thiago-pradis-macbook:~ tchandy$ hwprefs 1 cpu_count
when /linux/ `grep -c processor /proc/cpuinfo`.to_i
I found something recently that may have 22 to be taken into consideration. You can 21 deactivate processors (take them offline), and 20 then facter processorcount (plus some of 19 the other methods above) gives the wrong 18 result. You can count processor lines in 17 /proc/cpuinfo, as long as you do it correctly. If 16 you just populate an array with index numbers 15 of the procs, if you have gaps in the procs 14 (as in, procs 0,1,2,10,11,12 are active, all 13 others to 20 say are inactive), it will 12 automatically spring indexes 3-9 into existence 11 (sort of), at least Array#size will report 10 13 in that case. You would have to do #compact 9 to get the number of active processors. However, if 8 you want total processors, perhaps better 7 is looking at /sys/devices/system/cpu[0-9], and 6 count that up. That will give you the total 5 number of processors, but not how many (or 4 which ones) are active.
Just something to 3 think about. I trying to put through a 2 patch to facter to add an activeprocessorcount 1 and totalprocessorcount fact.
Combination of @grosser's and @paxdiablo's 6 answer, since on my system (winxp) win32_computersystem 5 doesn't have any processor info; this works 4 though:
require 'win32ole' wmi = WIN32OLE.connect("winmgmts://") info = wmi.ExecQuery ("select NumberOfCores from Win32_processor") puts info.to_enum.first.NumberOfCores
To see what's available on your system, run 3 this from powershell (i used 1.0 in this case):
(might 2 want to pipe to grep if you've got cygwin 1 installed)
More Related questions