Detect number of CPUs installed

前端 未结 12 879
孤城傲影
孤城傲影 2020-12-24 05:29

I already found a solution for \"Most unixes\" via cat /proc/cpuinfo, but a pure-Ruby solution would be nicer.

相关标签:
12条回答
  • 2020-12-24 06:00

    I am currently using this, which covers 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
    
    0 讨论(0)
  • 2020-12-24 06:04

    EDIT: Now rails ships with concurrent-ruby as a dependency so it's probably the best 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/root/Concurrent.html for more info. Because it does both physical and logical cores, it's better than the inbuilt Etc.nprocessors.

    and here is the 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 want other facts about the system too, it's not platform specific and designed to do this exact thing.

    UPDATE: updated to include Nathan Kleyn's tip on the api change.

    0 讨论(0)
  • 2020-12-24 06:04

    I tried using Facter but found it a bit slow. I tried system gem and found it a lot faster. It is also very easy to use: System::CPU.count.

    0 讨论(0)
  • 2020-12-24 06:05

    I found something recently that may have to be taken into consideration. You can deactivate processors (take them offline), and then facter processorcount (plus some of the other methods above) gives the wrong result. You can count processor lines in /proc/cpuinfo, as long as you do it correctly. If you just populate an array with index numbers of the procs, if you have gaps in the procs (as in, procs 0,1,2,10,11,12 are active, all others to 20 say are inactive), it will automatically spring indexes 3-9 into existence (sort of), at least Array#size will report 13 in that case. You would have to do #compact to get the number of active processors. However, if you want total processors, perhaps better is looking at /sys/devices/system/cpu[0-9], and count that up. That will give you the total number of processors, but not how many (or which ones) are active.

    Just something to think about. I trying to put through a patch to facter to add an activeprocessorcount and totalprocessorcount fact.

    0 讨论(0)
  • 2020-12-24 06:06

    Combination of @grosser's and @paxdiablo's answer, since on my system (winxp) win32_computersystem doesn't have any processor info; this works 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 this from powershell (i used 1.0 in this case):

    Get-WmiObject -list
    

    (might want to pipe to grep if you've got cygwin installed)

    0 讨论(0)
  • 2020-12-24 06:14

    Surely if you can cat it, you can open, read and close it using the standard features of the language without resorting to a system()-type call.

    You may just need to detect what platform you're on dynamically and either:

    • use the /proc/cpuinfo "file" for Linux; or
    • communicate with WMI for Windows.

    That last line can use:

    require 'win32ole'
    wmi = WIN32OLE.connect("winmgmts://")
    info = wmi.ExecQuery ("select * from Win32_ComputerSystem")
    

    Then use info's NumberOfProcessors item.

    0 讨论(0)
提交回复
热议问题