2009-05-21 15 views

Respuesta

25

Actualmente somos nosotros ing esto, que cubre todo 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 
+5

Si copia y pega este método fuera de Parallel, también necesitará extraer el método 'hwprefs_available', o mejor, requerir la gema y llamar a' Parallel.processor_count'. – mrm

+0

La biblioteca 'Parallel' se ha actualizado y el método' processor_count' ahora está en https://github.com/grosser/parallel/blob/master/lib/parallel/processor_count.rb – hnakamur

+0

Tenga en cuenta que NumberOfCores solo le brinda la cantidad de núcleos físicos de una CPU en el sistema. Tienes que multiplicar eso por el número de CPU (ver la respuesta de Konstantin Haases a continuación) ... – Bim

5

Seguramente si puede cat, puede abrirlo, leerlo y cerrarlo usando las características estándar del idioma sin recurrir a una llamada de tipo system()-type.

es posible que sólo tenga que detectar qué plataforma estás en forma dinámica y, o bien:

  • utilice el "archivo" /proc/cpuinfo para Linux; o
  • comunicarse con WMI para Windows.

Esa última línea se puede utilizar:

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

A continuación, utilice una pieza de información NumberOfProcessors.

+0

O posiblemente NumberOfProcessors. ;-) Gracias – Stobor

+0

, esperaba que sería algo fácil, por ahora voy a omitir esta característica :) Gracias – grosser

+0

, @Stobor, fijo. – paxdiablo

10

con JRuby se puede comprobar con el siguiente código Java:

Runtime runtime = Runtime.getRuntime(); 
int numberOfProcessors = runtime.availableProcessors(); 
+4

¡He votado esto particularmente debido al punto implícito de que con JRuby puedes usar esos núcleos adicionales con la clase de subprocesos de Ruby! ¿Valdría la pena agregar también esta versión del ejemplo? #!/Usr/bin/jruby incluye Java puts "Tiene # {java.lang.Runtime.getRuntime.availableProcessors} núcleos" –

36

EDIT: Ahora carriles barcos con concurrente-rubí como una dependencia por lo que es probablemente la mejor solución;

$ 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 

ver http://ruby-concurrency.github.io/concurrent-ruby/root/Concurrent.html para obtener más información.

y aquí está la respuesta anterior;

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

Este facter gem es la mejor si quieres otros hechos sobre el sistema también, que no es específica de la plataforma y diseñado para hacer esta cosa exacta.

ACTUALIZACIÓN: actualizado para incluir la sugerencia de Nathan Kleyn sobre el cambio de API.

+0

buena solución, compruebalo, ya que estoy trabajando en una biblioteca pública que hice No desea agregar una dependencia adicional para algo tan trivial – grosser

+0

Desafortunadamente, esto no detecta cpus hiperhebra. – jer

+0

+1 facter es genial, porque funciona multiplataforma! – Tilo

1

en Mac:

thiago-PRADIS-macbook: ~ tchandy $ hwprefs cpu_count

9

Aquí es una aplicación para Linux, OS X, Windows y BSD: https://gist.github.com/1009994

Fuente código:

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 
+1

Me gusta esta solución limpia. Funciona en mi sistema OpenBSD. –

0

encontré algo recientemente que puede tener que ser tomados en consideración.Puede desactivar procesadores (ponerlos fuera de línea), y luego facter processorcount (más algunos de los otros métodos anteriores) da el resultado incorrecto. Puede contar líneas de procesador en/proc/cpuinfo, siempre que lo haga correctamente. Si usted acaba de rellenar una matriz con los números de índice de las procsos, si usted tiene lagunas en los procs (como en procsos, 0,1,2,10,11,12 están activos, todos los demás a 20 por ejemplo están inactivas), lo hará automáticamente aparecen los índices 3-9 (más o menos), al menos el tamaño de Array # reportará 13 en ese caso. Tendría que hacer #compact para obtener la cantidad de procesadores activos. Sin embargo, si quiere procesadores totales, quizás sea mejor mirar/sys/devices/system/cpu [0-9], y contar eso. Eso le dará la cantidad total de procesadores, pero no cuántos (o cuáles) están activos.

Sólo algo en que pensar. Estoy tratando de pasar un parche a un facter para agregar un contador activo de proceso y hecho de cuenta total de proceso.

2

He intentado utilizar Facter pero nos pareció un poco lento. Probé la gema system y la encontré mucho más rápido. También es muy fácil de usar: System::CPU.count.

0

Combinación de respuesta @ @ paxdiablo de grosera y de, ya que en mi sistema (WinXP) Win32_ComputerSystem no tiene ninguna información del procesador; esto funciona sin embargo:

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

Para ver lo que está disponible en su sistema, ejecute esto desde powershell (i utilizado 1.0 en este caso):

Get-WmiObject -list 

(puede ser que desee tubería a grep si tienes tiene instalado cygwin)

3

En Linux también puede usar nproc, que es más limpio que las otras soluciones basadas en subshell aquí. Quería que vagabundo le diera la misma cantidad de CPU a la máquina virtual que el host. He añadido esto a Vagrantfile:

vb.cpus = `nproc`.to_i 
26

A partir de la versión 2.2.3 de Ruby, el módulo etc en stdlib de Ruby ofrece un método nprocessors que devuelve el número de procesadores. La advertencia a esto, es que si el rubí es relegado a un subconjunto de núcleos de CPU, Etc.nprocessors sólo devolverá el número de núcleos que Ruby tiene acceso. Además, como señaló seanlinsley, esto solo devolverá núcleos virtuales en lugar de núcleos físicos, lo que puede dar como resultado una disparidad en el valor esperado.

require 'etc' 
p Etc.nprocessors #=> 4 
+1

Desafortunadamente, devuelve núcleos virtuales en lugar de núcleos físicos, y no hay un método en 'Etc' para obtener núcleos físicos. – seanlinsley

+0

Gracias por el aviso @seanlinsley. He editado mi respuesta para dejar eso en claro. –

Cuestiones relacionadas