Détecter le nombre de processeurs installés

J'ai déjà trouvé une solution pour" la plupart des unixes " via cat /proc/cpuinfo, mais une solution pure-Ruby serait plus agréable.

36
demandé sur Tshepang 2009-05-21 09:42:49

12 réponses

EDIT: maintenant rails est livré avec concurrent-ruby en tant que dépendance, donc c'est probablement la meilleure 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

Voir http://ruby-concurrency.github.io/concurrent-ruby/root/Concurrent.html pour plus d'informations.

Et voici la réponse précédente;

$ 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> 

Ce facter gem est le meilleur si vous voulez d'autres faits sur le système aussi, ce n'est pas spécifique à la plate-forme et conçu pour faire cette chose exacte.

UPDATE: Mise à jour pour inclure L'astuce de Nathan Kleyn sur l'api changement.

37
répondu Anko 2017-08-15 22:58:38

À partir de la version 2.2.3 de Ruby, le etc module dans Stdlib de Ruby offre un nprocessors méthode qui renvoie le nombre de processeurs. La mise en garde à cela, est que si ruby est relégué à un sous-ensemble de cœurs de processeur, Etc.nprocessors ne retournera que le nombre de cœurs auxquels Ruby a accès. En outre, comme l'a souligné seanlinsley, cela ne retournera que des cœurs virtuels au lieu de cœurs physiques, ce qui peut entraîner une disparité dans la valeur attendue.

require 'etc'
p Etc.nprocessors #=> 4
29
répondu Brandon Anzaldi 2017-05-23 12:34:34

J'utilise actuellement ceci, qui couvre tous les systèmes d'exploitation. 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
26
répondu grosser 2011-08-14 19:46:38

Avec JRuby vous pouvez le vérifier avec le code Java suivant:

 Runtime runtime = Runtime.getRuntime();   
 int numberOfProcessors = runtime.availableProcessors(); 
10
répondu dfa 2009-05-21 06:39:07

Voici une implémentation Pour Linux, OSX, Windows et BSD: https://gist.github.com/1009994

Code Source:

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
9
répondu Konstantin Haase 2015-09-03 08:57:18

Certes, si vous le pouvez cat, vous pouvez l'ouvrir, le lire et le fermer en utilisant les fonctionnalités standard de la langue sans avoir recours à un appel de type system().

Vous devrez peut-être simplement détecter la plate-forme sur laquelle vous êtes dynamiquement et soit:

  • utiliser le /proc/cpuinfo "fichier" pour Linux; ou
  • communiquer avec WMI pour Windows.

Cette dernière ligne peut utiliser:

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

Ensuite, utilisez l'élément NumberOfProcessors d'info.

5
répondu paxdiablo 2009-05-21 06:10:17

J'ai essayé d'utiliser Facter mais je l'ai trouvé un peu lent. J'ai essayé system gem et l'ai trouvé beaucoup plus vite. Il est également très facile à utiliser: System::CPU.count.

3
répondu ioquatix 2013-10-19 08:52:30

Sous linux, vous pouvez également utiliser nproc, qui est plus propre que les autres solutions basées sur un sous-shell ici. Je voulais que vagrant donne le même nombre de processeurs à la machine virtuelle que l'hôte. J'ai ajouté ceci à Vagrantfile:

vb.cpus = `nproc`.to_i
3
répondu Paul Tobias 2015-04-15 10:50:29

Sur Mac:

Thiago-pradis-macbook: ~ tchandy$ hwprefs cpu_count

2

1
répondu 2009-07-31 23:19:38

@ grosser:

when /linux/  
  `grep -c processor /proc/cpuinfo`.to_i

Http://www.partmaps.org/era/unix/award.html#cat
http://www.partmaps.org/era/unix/award.html#wc

1
répondu Guest 2011-07-07 14:55:14

J'ai trouvé quelque chose récemment qui pourrait devoir être pris en considération. Vous pouvez désactiver les processeurs (les mettre hors ligne), puis facter processorcount (plus certaines des autres méthodes ci-dessus) donne le mauvais résultat. Vous pouvez compter les lignes de processeur dans / proc / cpuinfo, tant que vous le faites correctement. Si vous remplissez simplement un tableau avec les numéros d'index des procs, si vous avez des lacunes dans les procs (comme dans, les procs 0,1,2,10,11,12 sont actifs, tous les autres à 20 disent sont inactifs), il le fera automatiquement les index 3-9 dans l'existence (en quelque sorte), au moins Array # size rapportera 13 dans ce cas. Vous devriez faire #compact pour obtenir le nombre de processeurs actifs. Cependant, si vous voulez des processeurs totaux, peut-être mieux vaut regarder /sys / devices/system / cpu[0-9], et Compter cela. Cela vous donnera le nombre total de processeurs, mais pas combien (ou lesquelles) sont actifs.

Juste quelque chose à penser. J'essaie de mettre un patch à facter pour ajouter un activeprocessorcount et totalprocessorcount fait.

0
répondu lsd 2013-05-09 17:48:13

Combinaison de la réponse de @grosser et @paxdiablo, puisque sur mon Système (winxp) win32_computersystem n'a aucune information de processeur; cela fonctionne cependant:

require 'win32ole'
wmi = WIN32OLE.connect("winmgmts://")
info = wmi.ExecQuery ("select NumberOfCores from Win32_processor")
puts info.to_enum.first.NumberOfCores

Pour voir ce qui est disponible sur votre système, exécutez ceci à partir de powershell (j'ai utilisé 1.0 dans ce cas):

Get-WmiObject -list

(peut vouloir rediriger vers grep si cygwin est installé)

0
répondu fakeleft 2015-01-08 14:22:59