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.
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.
À 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
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
Avec JRuby vous pouvez le vérifier avec le code Java suivant:
Runtime runtime = Runtime.getRuntime();
int numberOfProcessors = runtime.availableProcessors();
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
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.
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
.
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
@ 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
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.
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é)